What is Fast DDS?

eProsima

eProsima Fast DDS is a C++ implementation of the DDS (Data Distribution Service) Specification, a protocol defined by the Object Management Group (OMG). The eProsima Fast DDS library provides both an Application Programming Interface (API) and a communication protocol that deploy a Data-Centric Publisher-Subscriber (DCPS) model, with the purpose of establishing efficient and reliable information distribution among Real-Time Systems.


Commercial support

Looking for commercial support? Write us to info@eprosima.com

Find more about us at eProsima’s webpage.

Key features

eProsima Fast DDS is predictable, scalable, flexible, and efficient in resource handling. For meeting these requirements, it makes use of typed interfaces and hinges on a many-to-many distributed network paradigm that neatly allows separation of the publisher and subscriber sides of the communication. eProsima Fast DDS comprises:

  • The DDS API implementation.

  • Fast DDS-Gen, a generation tool for bridging typed interfaces with the middleware implementation.

  • The underlying RTPS wire protocol implementation.

For all the above, eProsima Fast DDS has been chosen as the default middleware supported by the Robot Operating System 2 (ROS 2) in every long term (LTS) releases and most of the non-LTS releases.

DDS API

The communication model adopted by DDS is a many-to-many unidirectional data exchange where the applications that produce the data publish it to the local caches of subscribers belonging to applications that consume the data. The information flow is regulated by Quality of Service (QoS) policies established between the entities in charge of the data exchange.

As a data-centric model, DDS builds on the concept of a “global data space” accessible to all interested applications. Applications that want to contribute information declare their intent to become publishers, whereas applications that want to access portions of the data space declare their intent to become subscribers. Each time a publisher posts new data into this space, the middleware propagates the information to all interested subscribers.

The communication happens across domains, i. e. isolated abstract planes that link all the distributed applications able to communicate with each other. Only entities belonging to a same domain can interact, and the matching between entities subscribing to data and entities publishing them is mediated by topics. Topics are unambiguous identifiers that associate a name, which is unique in the domain, to a data type and a set of attached data-specific QoS.

DDS entities are modeled either as classes or typed interfaces. The latter imply a more efficient resource handling as knowledge of the data type prior to the execution allows allocating memory in advance rather than dynamically.

_images/DDS_concept.svg

Conceptual diagram of how information flows within DDS domains. Only entities belonging to the same domain can discover each other through matching topics, and consequently exchange data between publishers and subscribers.

Fast DDS-Gen

Relying on interfaces implies the need for a generation tool that translates type descriptions into appropriate implementations that fill the gap between the interfaces and the middleware. This task is carried out by a dedicated generation tool, Fast DDS-Gen, a Java application that generates source code using the data types defined in an Interface Definition Language (IDL) file.

RTPS Wire Protocol

The protocol used by eProsima Fast DDS to exchange messages over standard networks is the Real-Time Publish-Subscribe protocol (RTPS), an interoperability wire protocol for DDS defined and maintained by the OMG consortium. This protocol provides publisher-subscriber communications over transports such as TCP/UDP/IP, and guarantees compatibility among different DDS implementations.

Given its publish-subscribe roots and its specification designed for meeting the same requirements addressed by the DDS application domain, the RTPS protocol maps to many DDS concepts and is therefore a natural choice for DDS implementations. All the RTPS core entities are associated with an RTPS domain, which represents an isolated communication plane where endpoints match. The entities specified in the RTPS protocol are in one-to-one correspondence with the DDS entities, thus allowing the communication to occur.

Main Features

  • Two API Layers. eProsima Fast DDS comprises a high-level DDS compliant layer focused on usability and a lower-level RTPS compliant layer that provides finer access to the RTPS protocol.

  • Real-Time behaviour. eProsima Fast DDS can be configured to offer real-time features, guaranteeing responses within specified time constrains.

  • Built-in Discovery Server. eProsima Fast DDS is based on the dynamical discovery of existing publishers and subscribers, and performs this task continuously without the need to contacting or setting any servers. However, a Client-Server discovery as well as other discovery paradigms can also be configured.

  • Sync and Async publication modes. eProsima Fast DDS supports both synchronous and asynchronous data publication.

  • Best effort and reliable communication. eProsima Fast DDS supports an optional reliable communication paradigm over Best Effort communications protocols such as UDP. Furthermore, another way of setting a reliable communication is to use our TCP transport.

  • Transport layers. eProsima Fast DDS implements an architecture of pluggable transports. The current version implements five transports: UDPv4, UDPv6, TCPv4, TCPv6 and SHM (shared memory).

  • Security. eProsima Fast DDS can be configured to provide secure communications. For this purpose, it implements pluggable security at three levels: authentication of remote participants, access control of entities and encryption of data.

  • Statistics Module. eProsima Fast DDS can be configured to gather and provide information about the data being exchanged by the user application.

  • Flow controllers. We support user-configurable flow controllers, that can be used to limit the amount of data to be sent under certain conditions.

  • Plug-and-play Connectivity. New applications and services are automatically discovered, and can join and leave the network at any time without the need for reconfiguration.

  • Scalability and Flexibility. DDS builds on the concept of a global data space. The middleware is in charge of propagating the information between publishers and subscribers. This guarantees that the distributed network is adaptable to reconfigurations and scalable to a large number of entities.

  • Application Portability. The DDS specification includes a platform specific mapping to IDL, allowing an application using DDS to switch among DDS implementations with only a re-compile.

  • Extensibility. eProsima Fast DDS allows the protocol to be extended and enhanced with new services without breaking backwards compatibility and interoperability.

  • Configurability and Modularity. eProsima Fast DDS provides an intuitive way to be configured, either through code or XML profiles. Modularity allows simple devices to implement a subset of the protocol and still participate in the network.

  • High performance. eProsima Fast DDS uses a static low-level serialization library, Fast CDR, a C++ library that serializes according to the standard CDR serialization mechanism defined in the RTPS Specification (see the Data Encapsulation chapter as a reference).

  • Easy to use. The project comes with an out-of-the-box example, the DDSHelloWorld (see Getting Started) that puts into communication a publisher and a subscriber, showcasing how eProsima Fast DDS is deployed. Additionally, the interactive demo ShapesDemo is available for the user to dive into the DDS world. The DDS and the RTPS layers are thoroughly explained in the DDS Layer and RTPS Layer sections.

  • Low resources consumption. eProsima Fast DDS:

    • Allows to preallocate resources, to minimize dynamic resource allocation.

    • Avoids the use of unbounded resources.

    • Minimizes the need to copy data.

  • Multi-platform. The OS dependencies are treated as pluggable modules. Users may easily implement platform modules using the eProsima Fast DDS library on their target platforms. By default, the project can run over Linux, Windows and MacOS.

  • Free and Open Source. The Fast DDS library, the underneath RTPS library, the generator tool, the internal dependencies (such as eProsima Fast CDR) and the external ones (such as the foonathan library) are free and open source.

Dependencies and compatibilities

eProsima Fast DDS is continuously evolving and improving. This means that the different software products that are part of the Fast DDS ecosystem are evolving and improving together with Fast DDS.

Fast DDS has some library dependencies, e.g. the previously mentioned Fast CDR for data serialization, or OpenSSL for secure communications. Depending on different platform support levels, it has also different build dependencies.

Finally, there are some other eProsima products that use Fast DDS as a middleware, such as Micro XRCE-DDS, DDS Router and Fast DDS python wrapper. Those that are strongly attached to each Fast DDS supported version are described in this product compatibility table.

Contributing to the documentation

Fast DDS-Docs is an open source project, and as such all contributions, both in the form of feedback and content generation, are most welcomed. To make such contributions, please refer to the Contribution Guidelines hosted in our GitHub repository.

Structure of the documentation

This documentation is organized into the sections below.

The documentation includes a Frequently Asked Questions (FAQ) section that can be consulted for a quick overview.

What is Fast DDS?

eProsima

eProsima Fast DDS is a C++ implementation of the DDS (Data Distribution Service) Specification, a protocol defined by the Object Management Group (OMG). The eProsima Fast DDS library provides both an Application Programming Interface (API) and a communication protocol that deploy a Data-Centric Publisher-Subscriber (DCPS) model, with the purpose of establishing efficient and reliable information distribution among Real-Time Systems.


Commercial support

Looking for commercial support? Write us to info@eprosima.com

Find more about us at eProsima’s webpage.

Key features

eProsima Fast DDS is predictable, scalable, flexible, and efficient in resource handling. For meeting these requirements, it makes use of typed interfaces and hinges on a many-to-many distributed network paradigm that neatly allows separation of the publisher and subscriber sides of the communication. eProsima Fast DDS comprises:

  • The DDS API implementation.

  • Fast DDS-Gen, a generation tool for bridging typed interfaces with the middleware implementation.

  • The underlying RTPS wire protocol implementation.

For all the above, eProsima Fast DDS has been chosen as the default middleware supported by the Robot Operating System 2 (ROS 2) in every long term (LTS) releases and most of the non-LTS releases.

DDS API

The communication model adopted by DDS is a many-to-many unidirectional data exchange where the applications that produce the data publish it to the local caches of subscribers belonging to applications that consume the data. The information flow is regulated by Quality of Service (QoS) policies established between the entities in charge of the data exchange.

As a data-centric model, DDS builds on the concept of a “global data space” accessible to all interested applications. Applications that want to contribute information declare their intent to become publishers, whereas applications that want to access portions of the data space declare their intent to become subscribers. Each time a publisher posts new data into this space, the middleware propagates the information to all interested subscribers.

The communication happens across domains, i. e. isolated abstract planes that link all the distributed applications able to communicate with each other. Only entities belonging to a same domain can interact, and the matching between entities subscribing to data and entities publishing them is mediated by topics. Topics are unambiguous identifiers that associate a name, which is unique in the domain, to a data type and a set of attached data-specific QoS.

DDS entities are modeled either as classes or typed interfaces. The latter imply a more efficient resource handling as knowledge of the data type prior to the execution allows allocating memory in advance rather than dynamically.

_images/DDS_concept.svg

Conceptual diagram of how information flows within DDS domains. Only entities belonging to the same domain can discover each other through matching topics, and consequently exchange data between publishers and subscribers.

Fast DDS-Gen

Relying on interfaces implies the need for a generation tool that translates type descriptions into appropriate implementations that fill the gap between the interfaces and the middleware. This task is carried out by a dedicated generation tool, Fast DDS-Gen, a Java application that generates source code using the data types defined in an Interface Definition Language (IDL) file.

RTPS Wire Protocol

The protocol used by eProsima Fast DDS to exchange messages over standard networks is the Real-Time Publish-Subscribe protocol (RTPS), an interoperability wire protocol for DDS defined and maintained by the OMG consortium. This protocol provides publisher-subscriber communications over transports such as TCP/UDP/IP, and guarantees compatibility among different DDS implementations.

Given its publish-subscribe roots and its specification designed for meeting the same requirements addressed by the DDS application domain, the RTPS protocol maps to many DDS concepts and is therefore a natural choice for DDS implementations. All the RTPS core entities are associated with an RTPS domain, which represents an isolated communication plane where endpoints match. The entities specified in the RTPS protocol are in one-to-one correspondence with the DDS entities, thus allowing the communication to occur.

Main Features

  • Two API Layers. eProsima Fast DDS comprises a high-level DDS compliant layer focused on usability and a lower-level RTPS compliant layer that provides finer access to the RTPS protocol.

  • Real-Time behaviour. eProsima Fast DDS can be configured to offer real-time features, guaranteeing responses within specified time constrains.

  • Built-in Discovery Server. eProsima Fast DDS is based on the dynamical discovery of existing publishers and subscribers, and performs this task continuously without the need to contacting or setting any servers. However, a Client-Server discovery as well as other discovery paradigms can also be configured.

  • Sync and Async publication modes. eProsima Fast DDS supports both synchronous and asynchronous data publication.

  • Best effort and reliable communication. eProsima Fast DDS supports an optional reliable communication paradigm over Best Effort communications protocols such as UDP. Furthermore, another way of setting a reliable communication is to use our TCP transport.

  • Transport layers. eProsima Fast DDS implements an architecture of pluggable transports. The current version implements five transports: UDPv4, UDPv6, TCPv4, TCPv6 and SHM (shared memory).

  • Security. eProsima Fast DDS can be configured to provide secure communications. For this purpose, it implements pluggable security at three levels: authentication of remote participants, access control of entities and encryption of data.

  • Statistics Module. eProsima Fast DDS can be configured to gather and provide information about the data being exchanged by the user application.

  • Flow controllers. We support user-configurable flow controllers, that can be used to limit the amount of data to be sent under certain conditions.

  • Plug-and-play Connectivity. New applications and services are automatically discovered, and can join and leave the network at any time without the need for reconfiguration.

  • Scalability and Flexibility. DDS builds on the concept of a global data space. The middleware is in charge of propagating the information between publishers and subscribers. This guarantees that the distributed network is adaptable to reconfigurations and scalable to a large number of entities.

  • Application Portability. The DDS specification includes a platform specific mapping to IDL, allowing an application using DDS to switch among DDS implementations with only a re-compile.

  • Extensibility. eProsima Fast DDS allows the protocol to be extended and enhanced with new services without breaking backwards compatibility and interoperability.

  • Configurability and Modularity. eProsima Fast DDS provides an intuitive way to be configured, either through code or XML profiles. Modularity allows simple devices to implement a subset of the protocol and still participate in the network.

  • High performance. eProsima Fast DDS uses a static low-level serialization library, Fast CDR, a C++ library that serializes according to the standard CDR serialization mechanism defined in the RTPS Specification (see the Data Encapsulation chapter as a reference).

  • Easy to use. The project comes with an out-of-the-box example, the DDSHelloWorld (see Getting Started) that puts into communication a publisher and a subscriber, showcasing how eProsima Fast DDS is deployed. Additionally, the interactive demo ShapesDemo is available for the user to dive into the DDS world. The DDS and the RTPS layers are thoroughly explained in the DDS Layer and RTPS Layer sections.

  • Low resources consumption. eProsima Fast DDS:

    • Allows to preallocate resources, to minimize dynamic resource allocation.

    • Avoids the use of unbounded resources.

    • Minimizes the need to copy data.

  • Multi-platform. The OS dependencies are treated as pluggable modules. Users may easily implement platform modules using the eProsima Fast DDS library on their target platforms. By default, the project can run over Linux, Windows and MacOS.

  • Free and Open Source. The Fast DDS library, the underneath RTPS library, the generator tool, the internal dependencies (such as eProsima Fast CDR) and the external ones (such as the foonathan library) are free and open source.

Dependencies and compatibilities

eProsima Fast DDS is continuously evolving and improving. This means that the different software products that are part of the Fast DDS ecosystem are evolving and improving together with Fast DDS.

Fast DDS has some library dependencies, e.g. the previously mentioned Fast CDR for data serialization, or OpenSSL for secure communications. Depending on different platform support levels, it has also different build dependencies.

Finally, there are some other eProsima products that use Fast DDS as a middleware, such as Micro XRCE-DDS, DDS Router and Fast DDS python wrapper. Those that are strongly attached to each Fast DDS supported version are described in this product compatibility table.

Contributing to the documentation

Fast DDS-Docs is an open source project, and as such all contributions, both in the form of feedback and content generation, are most welcomed. To make such contributions, please refer to the Contribution Guidelines hosted in our GitHub repository.

Structure of the documentation

This documentation is organized into the sections below.

The documentation includes a Frequently Asked Questions (FAQ) section that can be consulted for a quick overview.

1. Linux installation from binaries

The instructions for installing eProsima Fast DDS in a Linux environment from binaries are provided in this page.

1.1. Install

The latest release of eProsima Fast DDS for Linux is available at the eProsima website Downloads tab. Once downloaded, extract the contents in your preferred directory. Then, to install eProsima Fast DDS and all its dependencies in the system, execute the install.sh script with administrative privileges:

cd <extraction_directory>
sudo ./install.sh

Note

By default, eProsima Fast DDS does not compile tests. To activate them, please refer to the Linux installation from sources page.

1.1.1. Contents

The src folder contains the following packages:

  • foonathan_memory_vendor, an STL compatible C++ memory allocator library.

  • fastcdr, a C++ library for data serialization according to the CDR standard (Section 10.2.1.2 OMG CDR).

  • fastdds, the core library of eProsima Fast DDS library.

  • fastddsgen, a Java application that generates source code using the data types defined in an IDL file.

See also

For further information about Fast DDS dependencies, as well as for the corresponding versions of other related products, please refer to the Fast DDS Dependencies and compatibilities section.

In case any of these components is unwanted, it can be simply renamed or removed from the src directory.

1.1.2. Run an application

When running an instance of an application using eProsima Fast DDS, it must be linked with the library where the packages have been installed, /usr/local/lib/. There are two possibilities:

  • Prepare the environment locally by typing in the console used for running the eProsima Fast DDS instance the command:

    export LD_LIBRARY_PATH=/usr/local/lib/
    
  • Add it permanently to the PATH by executing:

    echo 'export LD_LIBRARY_PATH=/usr/local/lib/' >> ~/.bashrc
    

1.1.3. Including Fast-DDS in a CMake project

The installer deploys CMake config files that simplify to incorporate Fast-DDS to any CMake project via the find_package CMake API.

By setting the CMake variable BUILD_SHARED_LIBS is possible to choose the desired linkage (dynamic or static library) in the CMake generator stage. If the variable is missing build process will default to static linking.

For example in order to build the examples dynamically linked to Fast-DDS do:

$ cmake -Bbuildexample -DBUILD_SHARED_LIBS=ON .
$ cmake --build buildexample --target install

1.2. Fast DDS CLI (optional)

The Fast DDS CLI (Command Line Interface) is a tool that provides a set commands and sub-commands to perform, Fast DDS related, maintenance and configuration tasks. As an optional tool, its dependencies are not installed by default, but they can be installed by running the following command:

sudo apt-get install python3 python3-pip
pip3 install xmlschema

Python3 is required to run the CLI tool, and the xmlschema dependency is needed to use the XML validation command.

1.3. Uninstall

To uninstall all installed components, execute the uninstall.sh script (with administrative privileges):

cd <extraction_directory>
sudo ./uninstall.sh

Warning

If any of the other components were already installed in some other way in the system, they will be removed as well. To avoid it, edit the script before executing it.

2. Windows installation from binaries

The instructions for installing eProsima Fast DDS in a Windows environment from binaries are provided in this page. It is organized as follows:

First of all, the Requirements detailed below need to be met.

2.1. Requirements

The installation of eProsima Fast DDS in a Windows environment from binaries requires the following tools to be installed in the system:

2.1.1. Visual Studio

Visual Studio is required to have a C++ compiler in the system. For this purpose, make sure to check the Desktop development with C++ option during the Visual Studio installation process.

If Visual Studio is already installed but the Visual C++ Redistributable packages are not, open Visual Studio and go to Tools -> Get Tools and Features and in the Workloads tab enable Desktop development with C++. Finally, click Modify at the bottom right.

2.2. Install

The latest release of eProsima Fast DDS for Windows is available at the company website downloads page. Once downloaded, execute the installer and follow the instructions, choosing the preferred Visual Studio version and architecture when prompted.

Note

By default, eProsima Fast DDS does not compile tests. To activate them, please refer to the Windows installation from sources page.

To use the xml validation tool, please refer to the Windows installation from sources page.

2.2.1. Contents

By default, the installation will download all the available packages, namely:

  • foonathan_memory_vendor, an STL compatible C++ memory allocator library.

  • fastcdr, a C++ library that serializes according to the standard CDR serialization mechanism.

  • fastdds, the core library of eProsima Fast DDS library.

  • fastddsgen, a Java application that generates source code using the data types defined in an IDL file.

See also

For further information about Fast DDS dependencies, as well as for the corresponding versions of other related products, please refer to the Fast DDS Dependencies and compatibilities section.

2.2.2. Environment variables

eProsima Fast DDS requires the following environment variable setup in order to function properly:

  • FASTDDSHOME: Root folder where eProsima Fast DDS is installed.

  • Additions to the PATH: The location of eProsima Fast DDS scripts and libraries should be appended to the PATH.

These variables are set automatically by checking the corresponding box during the installation process.

2.2.3. Including Fast-DDS in a CMake project

The installer deploys CMake config files that simplify to incorporate Fast-DDS to any CMake project via the find_package CMake API.

Shared and static libraries are provided by the installer. The user can select which one will be used in the CMake project using next mechanisms.

  1. Through CMake package components when calling find_package().

    find_package(fastdds shared) # Load shared library target
    find_package(fastdds static) # Load static library target
    
  2. Through the custom CMake variable fastdds_SHARED_LIBS.

    cmake -Dfastdds_SHARED_LIBS=ON .. # Load shared library target
    cmake -Dfastdds_SHARED_LIBS=OFF .. # Load static library target
    
  3. Through the built-in CMake variable BUILD_SHARED_LIBS.

    cmake -DBUILD_SHARED_LIBS=ON .. # Load shared library target
    cmake -DBUILD_SHARED_LIBS=OFF .. # Load static library target
    
  4. In case no previous mechanism is used, CMake will try to load static library target. If it fails then CMake will try to load shared library target.

For example in order to build the examples dynamically linked to Fast-DDS do:

cmake -Bbuildexample -DBUILD_SHARED_LIBS=ON .
cmake --build buildexample --target install

2.3. Fast DDS CLI (optional)

The Fast DDS CLI (Command Line Interface) is a tool that provides a set commands and sub-commands to perform, Fast DDS related, maintenance and configuration tasks. As an optional tool, its dependencies are not installed by default, but they can be installed by running the following command:

choco install python
python -m pip install --upgrade pywin32 xmlschema

Python3 is required to run the CLI tool, and the xmlschema dependency is needed to use the XML validation command.

3. Linux installation from sources

The instructions for installing the Fast DDS library, the Fast DDS Python bindings and the Fast DDS-Gen generation tool from sources are provided in this page. It is organized as follows:

3.1. Fast DDS library installation

This section describes the instructions for installing eProsima Fast DDS in a Linux environment from sources. The following packages will be installed:

  • foonathan_memory_vendor, an STL compatible C++ memory allocator library.

  • fastdds_gen, a Java application that generates source code using the data types defined in an IDL file.

  • fastcdr, a C++ library that serializes according to the standard CDR serialization mechanism.

  • fastdds, the core library of eProsima Fast DDS library.

First of all, the Requirements and Dependencies detailed below need to be met. Afterwards, the user can choose whether to follow either the colcon or the CMake installation instructions.

3.1.1. Requirements

The installation of eProsima Fast DDS in a Linux environment from sources requires the following tools to be installed in the system:

3.1.1.1. CMake, g++, pip3, wget and git

These packages provide the tools required to install eProsima Fast DDS and its dependencies from command line. Install CMake, g++, pip3, wget and git using the package manager of the appropriate Linux distribution. For example, on Ubuntu use the command:

sudo apt install cmake g++ python3-pip wget git

3.1.2. Dependencies

eProsima Fast DDS has the following dependencies, when installed from sources in a Linux environment:

See also

For further information about this Fast DDS version dependencies, as well as for the corresponding versions of other related products, please refer to the Fast DDS Library dependencies section.

3.1.2.1. Asio and TinyXML2 libraries

Asio is a cross-platform C++ library for network and low-level I/O programming, which provides a consistent asynchronous model. TinyXML2 is a simple, small and efficient C++ XML parser. Install these libraries using the package manager of the appropriate Linux distribution. For example, on Ubuntu use the command:

sudo apt install libasio-dev libtinyxml2-dev
3.1.2.2. OpenSSL

OpenSSL is a robust toolkit for the TLS and SSL protocols and a general-purpose cryptography library. Install OpenSSL using the package manager of the appropriate Linux distribution. For example, on Ubuntu use the command:

sudo apt install libssl-dev
3.1.2.3. Libp11 and SoftHSM libraries

Libp11 provides PKCS#11 support for OpenSSL. This is an optional dependency, that is needed only when eprosima Fast DDS is used with security and PKCS#11 URIs.

Install libp11 using the package manager of the appropriate Linux distribution. For example, on Ubuntu use the command:

sudo apt install libp11-dev

SoftHSM is a software implementation of an HSM (Hardware Security Module). If eProsima Fast DDS tests are activated and libp11 is installed on the system, SoftHSM is additionally required to run tests of PKCS#11 features.

Install SoftHSM using the package manager of the appropriate Linux distribution. For example, on Ubuntu use the command:

sudo apt install softhsm2

Note that the softhsm2 package creates a new group called softhsm. In order to grant access to the HSM module a user must belong to this group.

sudo usermod -a -G softhsm <user>

OpenSSL access HSM and other hardware devices through its engine functionality. In order to set up a new engine the OpenSSL configuration files (usually /etc/ssl/openssl.cnf) must be updated specifying the libp11 and hardware module (here SoftHSM) dynamic libraries location.

This configuration step can be avoided using p11kit which allows OpenSSL to find PKCS#11 devices on runtime without static configuration. This kit is often available through the Linux distribution package manager. On Ubuntu, for example:

sudo apt install libengine-pkcs11-openssl

Once installed, to check p11kit is able to find the SoftHSM module use:

p11-kit list-modules

In order to check if OpenSSL is able to access PKCS#11 engine use:

openssl engine pkcs11 -t
3.1.2.4. Gtest

GTest is a unit testing library for C++. By default, eProsima Fast DDS does not compile tests. It is possible to activate them with the opportune CMake configuration options when calling colcon or CMake. For more details, please refer to the CMake options section. Also add the Gtest repository into the workspace directory.

git clone --branch release-1.11.0 https://github.com/google/googletest src/googletest-distribution
3.1.2.5. XML validation tool

XML validation is a new command introduced to validate the XML profiles against an XSD schema through Fast DDS CLI. That ensures the proper characterization of the entities using the xml profiles.

For more details, please refer to the xml section.

Install the xmlschema dependency to be able to use this optional tool.

3.1.3. Colcon installation

colcon is a command line tool based on CMake aimed at building sets of software packages. This section explains how to use it to compile eProsima Fast DDS and its dependencies.

  1. Install the ROS 2 development tools (colcon and vcstool) by executing the following command:

    pip3 install -U colcon-common-extensions vcstool
    

    Note

    Mind that under non-root users, pip3 may install python colcon and vcs executables in $HOME/.local/bin, for instance when running with --user. To be able to run these applications, make sure that pip3 binary installation directory is in your $PATH ($HOME/.local/bin is normally introduced while login on an interactive non-root shell).

  2. Create a Fast-DDS directory and download the repos file that will be used to install eProsima Fast DDS and its dependencies:

    mkdir ~/Fast-DDS
    cd ~/Fast-DDS
    wget https://raw.githubusercontent.com/eProsima/Fast-DDS/master/fastdds.repos
    mkdir src
    vcs import src < fastdds.repos
    
  3. Build the packages:

    colcon build --packages-up-to fastdds
    

Note

Being based on CMake, it is possible to pass CMake configuration options to the colcon build command. For more information on the specific syntax, please refer to the CMake specific arguments page of the colcon manual.

3.1.3.1. Run an application

When running an instance of an application using eProsima Fast DDS, the colcon overlay built in the dedicated Fast-DDS directory must be sourced. There are two possibilities:

  • Every time a new shell is opened, prepare the environment locally by typing the command:

    source ~/Fast-DDS/install/setup.bash
    
  • Add the sourcing of the colcon overlay permanently to the PATH, by typing the following:

    echo 'source ~/Fast-DDS/install/setup.bash' >> ~/.bashrc
    

3.1.4. CMake installation

This section explains how to compile eProsima Fast DDS with CMake, either locally or globally.

3.1.4.1. Local installation
  1. Create a Fast-DDS directory where to download and build eProsima Fast DDS and its dependencies:

    mkdir ~/Fast-DDS
    
  2. Clone the following dependencies and compile them using CMake.

    • Foonathan memory

      cd ~/Fast-DDS
      git clone https://github.com/eProsima/foonathan_memory_vendor.git
      mkdir foonathan_memory_vendor/build
      cd foonathan_memory_vendor/build
      cmake .. -DCMAKE_INSTALL_PREFIX=~/Fast-DDS/install -DBUILD_SHARED_LIBS=ON
      cmake --build . --target install
      
    • Fast CDR

      cd ~/Fast-DDS
      git clone https://github.com/eProsima/Fast-CDR.git
      mkdir Fast-CDR/build
      cd Fast-CDR/build
      cmake .. -DCMAKE_INSTALL_PREFIX=~/Fast-DDS/install
      cmake --build . --target install
      
  3. Once all dependencies are installed, install eProsima Fast DDS:

    cd ~/Fast-DDS
    git clone https://github.com/eProsima/Fast-DDS.git
    mkdir Fast-DDS/build
    cd Fast-DDS/build
    cmake ..  -DCMAKE_INSTALL_PREFIX=~/Fast-DDS/install
    cmake --build . --target install
    

Note

By default, eProsima Fast DDS does not compile tests. However, they can be activated by downloading and installing Gtest.

3.1.4.2. Global installation

To install eProsima Fast DDS system-wide instead of locally, remove all the flags that appear in the configuration steps of Fast-CDR and Fast-DDS, and change the first in the configuration step of foonathan_memory_vendor to the following:

-DCMAKE_INSTALL_PREFIX=/usr/local/ -DBUILD_SHARED_LIBS=ON

Note

Installation on system directories may need of permissions. Maybe permissions have to be granted through sudo.

sudo cmake --build . --target install
3.1.4.3. Run an application

When running an instance of an application using eProsima Fast DDS, it must be linked with the library where the packages have been installed, which in the case of system-wide installation is: /usr/local/lib/ (if local installation is used, adjust for the correct directory). There are two possibilities:

  • Prepare the environment locally by typing the command:

    export LD_LIBRARY_PATH=/usr/local/lib/
    
  • Add it permanently it to the PATH, by typing:

    echo 'export LD_LIBRARY_PATH=/usr/local/lib/' >> ~/.bashrc
    

3.2. Fast DDS Python bindings installation

This section provides the instructions for installing Fast DDS Python bindings in a Linux environment from sources. Fast DDS Python bindings is an extension of Fast DDS which provides access to the Fast DDS API through Python. Therefore, its installation is an extension of the installation of Fast DDS.

Fast DDS Python bindings source code consists on several .i files which will be processed by SWIG. Then C++ files (for connecting C++ and Python) and Python files (Python module for Fast DDS) will be generated.

First of all, the Requirements and Dependencies detailed below need to be met. Afterwards, the user can choose whether to follow either the colcon or the CMake installation instructions.

3.2.1. Requirements

The installation of Fast DDS Python bindings in a Linux environment from sources requires the following tools to be installed in the system:

3.2.1.1. SWIG

SWIG is a development tool that allows connecting programs written in C/C++ with a variety of other programming languages, among them Python. SWIG version lower than 4.2 is required to build Fast DDS Python bindings.

Note

More recent SWIG releases are not yet supported. Please, ensure to be using SWIG 4.0.

SWIG can be installed directly from the package manager of the appropriate Linux distribution. For Ubuntu, please run:

sudo apt install swig

Warning

For Ubuntu 24.04, SWIG must be installed using the following command:

sudo apt install swig4.1
3.2.1.2. Header files and static library for Python

Python static libraries and header files are needed to compile C++ source code generated by SWIG. They can be installed directly from the package manager of the appropriate Linux distribution. For Ubuntu, please run:

sudo apt install libpython3-dev

3.2.2. Dependencies

Fast DDS Python bindings has the following dependencies, when installed from sources in a Linux environment:

3.2.3. Colcon installation

colcon is a command line tool based on CMake aimed at building sets of software packages. This section explains how to use it to compile Fast DDS Python bindings and its dependencies.

  1. Install the ROS 2 development tools (colcon and vcstool) by executing the following command:

    pip3 install -U colcon-common-extensions vcstool
    

    Note

    If this fails due to an Environment Error, add the --user flag to the pip3 installation command.

  2. Create a Fast-DDS-python directory and download the repos file that will be used to install Fast DDS Python bindings and its dependencies:

    mkdir ~/Fast-DDS-python
    cd ~/Fast-DDS-python
    wget https://raw.githubusercontent.com/eProsima/Fast-DDS-python/main/fastdds_python.repos
    mkdir src
    vcs import src < fastdds_python.repos
    
  3. Build the packages:

    colcon build --packages-up-to fastdds_python
    

Note

Being based on CMake, it is possible to pass CMake configuration options to the colcon build command. For more information on the specific syntax, please refer to the CMake specific arguments page of the colcon manual.

3.2.3.1. Run an application

When running an instance of an application using Fast DDS Python bindings, the colcon overlay built in the dedicated Fast-DDS-python directory must be sourced. There are two possibilities:

  • Every time a new shell is opened, prepare the environment locally by typing the command:

    source ~/Fast-DDS-python/install/setup.bash
    
  • Add the sourcing of the colcon overlay permanently to the PATH, by typing the following:

    echo 'source ~/Fast-DDS-python/install/setup.bash' >> ~/.bashrc
    

3.2.4. CMake installation

This section explains how to compile Fast DDS Python bindings with CMake, either locally or globally.

3.2.4.1. Local installation
  1. Create a Fast-DDS-python directory where to download and build Fast DDS Python bindings and its dependencies:

    mkdir ~/Fast-DDS-python
    
  2. Clone the following dependencies and compile them using CMake.

    • Foonathan memory

      cd ~/Fast-DDS-python
      git clone https://github.com/eProsima/foonathan_memory_vendor.git
      mkdir foonathan_memory_vendor/build
      cd foonathan_memory_vendor/build
      cmake .. -DCMAKE_INSTALL_PREFIX=~/Fast-DDS-python/install -DBUILD_SHARED_LIBS=ON
      cmake --build . --target install
      
    • Fast CDR

      cd ~/Fast-DDS-python
      git clone https://github.com/eProsima/Fast-CDR.git
      mkdir Fast-CDR/build
      cd Fast-CDR/build
      cmake .. -DCMAKE_INSTALL_PREFIX=~/Fast-DDS-python/install
      cmake --build . --target install
      
    • Fast DDS

      cd ~/Fast-DDS-python
      git clone https://github.com/eProsima/Fast-DDS.git
      mkdir Fast-DDS/build
      cd Fast-DDS/build
      cmake .. -DCMAKE_INSTALL_PREFIX=~/Fast-DDS-python/install
      cmake --build . --target install
      
  3. Once all dependencies are installed, install Fast DDS Python bindings:

    cd ~/Fast-DDS-python
    git clone https://github.com/eProsima/Fast-DDS-python.git
    mkdir -p Fast-DDS-python/fastdds_python/build
    cd Fast-DDS-python/fastdds_python/build
    cmake ..  -DCMAKE_INSTALL_PREFIX=~/Fast-DDS-python/install
    cmake --build . --target install
    
3.2.4.2. Global installation

To install Fast DDS Python bindings system-wide instead of locally, remove all the flags that appear in the configuration steps of Fast-CDR, Fast-DDS and Fast-DDS-python, and change the first in the configuration step of foonathan_memory_vendor to the following:

-DCMAKE_INSTALL_PREFIX=/usr/local/ -DBUILD_SHARED_LIBS=ON

Note

Installation on system directories may need of permissions. Maybe permissions have to be granted through sudo.

sudo cmake --build . --target install
3.2.4.3. Run an application

When running an instance of an application using Fast DDS Python bindings, it must be linked with the library where the packages have been installed, which in the case of system-wide installation is: /usr/local/lib/ (if local installation is used, adjust for the correct directory). There are two possibilities:

  • Prepare the environment locally by typing the command:

    export LD_LIBRARY_PATH=/usr/local/lib/
    
  • Add it permanently it to the PATH, by typing:

    echo 'export LD_LIBRARY_PATH=/usr/local/lib/' >> ~/.bashrc
    

3.3. Fast DDS-Gen installation

This section provides the instructions for installing Fast DDS-Gen in a Linux environment from sources. Fast DDS-Gen is a Java application that generates source code using the data types defined in an IDL file. Please refer to Introduction for more information, and to eProsima products compatibility for the compatibility matrix against Fast DDS versions.

3.3.1. Requirements

Fast DDS-Gen is built using Gradle. Gradle is an open-source build automation tool which requires a Java version to be executed (see Gradle-Java compatibility matrix).

Important

Even though earlier versions of Gradle support Java 8, Fast DDS-Gen stopped supporting Java versions previous to Java 11 since release v2.4.0.

Important

Fast DDS-Gen introduced support for Gradle 7 in release v2.2.0. Gradle 8 is not yet supported.

See also

For further information about Fast DDS-Gen product related versions, please refer to the Library dependencies section.

3.3.1.1. Java JDK

The JDK is a development environment for building applications and components using the Java language. There are several versions of Java available. For instance, to install Java 11 JDK, run the following command:

sudo apt install openjdk-11-jdk

Note

Fast DDS-Gen supports Java versions from 11 to 19.

3.3.2. Compiling Fast DDS-Gen

In order to compile Fast DDS-Gen, an executable script is included in the repository which will download Gradle temporarily for the compilation step. Please, follow the steps below to build Fast DDS-Gen:

Note

If Fast DDS has already been installed following Colcon installation, skip cloning Fast DDS-Gen’s repository, as it can already be found under the src directory within the colcon workspace.

mkdir -p ~/Fast-DDS/src
cd ~/Fast-DDS/src
git clone --recursive https://github.com/eProsima/Fast-DDS-Gen.git fastddsgen
cd fastddsgen
./gradlew assemble

Note

In case that a supported Gradle version is already installed in the system, Fast DDS-Gen can also be built running directly:

gradle assemble
3.3.2.1. Contents

The Fast-DDS-Gen folder contains the following packages:

  • share/fastddsgen, where the generated Java application is.

  • scripts, containing some user friendly scripts.

    Note

    To make these scripts accessible from any shell session and directory, add the scripts folder path to the PATH environment variable.

4. Windows installation from sources

The instructions for installing both the Fast DDS library and the Fast DDS-Gen generation tool from sources are provided in this page. It is organized as follows:

4.1. Fast DDS library installation

This section provides the instructions for installing eProsima Fast DDS in a Windows environment from sources. The following packages will be installed:

  • foonathan_memory_vendor, an STL compatible C++ memory allocator library.

  • fastdds_gen, a Java application that generates source code using the data types defined in an IDL file.

  • fastcdr, a C++ library that serializes according to the standard CDR serialization mechanism.

  • fastdds, the core library of eProsima Fast DDS library.

First of all, the Requirements and Dependencies detailed below need to be met. Afterwards, the user can choose whether to follow either the colcon or the CMake installation instructions.

4.1.1. Requirements

The installation of eProsima Fast DDS in a Windows environment from sources requires the following tools to be installed in the system:

4.1.1.1. Visual Studio

Visual Studio is required to have a C++ compiler in the system. For this purpose, make sure to check the Desktop development with C++ option during the Visual Studio installation process.

If Visual Studio is already installed but the Visual C++ Redistributable packages are not, open Visual Studio and go to Tools -> Get Tools and Features and in the Workloads tab enable Desktop development with C++. Finally, click Modify at the bottom right.

4.1.1.2. Chocolatey

Chocolatey is a Windows package manager. It is needed to install some of eProsima Fast DDS’s dependencies. Download and install it directly from the website.

4.1.1.3. CMake, pip3, wget and git

These packages provide the tools required to install eProsima Fast DDS and its dependencies from command line. Download and install CMake, pip3, wget and git by following the instructions detailed in the respective websites. Once installed, add the path to the executables to the PATH from the Edit the system environment variables control panel.

4.1.1.4. Gtest

GTest is a unit testing library for C++. By default, eProsima Fast DDS does not compile tests. It is possible to activate them with the opportune CMake configuration options when calling colcon or CMake. For more details, please refer to the CMake options section. Also add the Gtest repository into the workspace directory.

git clone --branch release-1.11.0 https://github.com/google/googletest src/googletest-distribution

and add next argument to the colcon call

colcon build --cmake-args -Dgtest_force_shared_crt=ON
4.1.1.5. XML validation tool

XML validation is a new command introduced to validate the XML profiles against an XSD schema through Fast DDS CLI. That ensures the proper characterization of the entities using the xml profiles.

For more details, please refer to the xml section.

Install the xmlschema dependency to be able to use this optional tool.

4.1.2. Dependencies

eProsima Fast RTPS has the following dependencies, when installed from sources in a Windows environment:

See also

For further information about this Fast DDS version dependencies, as well as for the corresponding versions of other related products, please refer to the Fast DDS Library dependencies section.

4.1.2.1. Asio and TinyXML2 libraries

Asio is a cross-platform C++ library for network and low-level I/O programming, which provides a consistent asynchronous model. TinyXML2 is a simple, small and efficient C++ XML parser. They can be downloaded directly from the links below:

After downloading these packages, open an administrative shell with PowerShell and execute the following command:

choco install -y -s <PATH_TO_DOWNLOADS> asio tinyxml2

where <PATH_TO_DOWNLOADS> is the folder into which the packages have been downloaded.

4.1.2.2. OpenSSL

OpenSSL is a robust toolkit for the TLS and SSL protocols and a general-purpose cryptography library. Install it by running the following command inside an administrative shell with PowerShell:

choco install -y openssl
4.1.2.3. Libp11 and SoftHSM libraries

Libp11 provides PKCS#11 support for OpenSSL. This is an optional dependency, that is needed only when eprosima Fast DDS is used with security and PKCS#11 URIs.

Download the latest libp11 version for Windows from this repository and follow the installation instructions

SoftHSM is a software implementation of an HSM (Hardware Security Module). If eProsima Fast DDS tests are activated and libp11 is installed on the system, SoftHSM is additionally required to run tests of PKCS#11 features.

Download the SoftHSM for Windows installer from this repository. Execute the installer and follow the installation instructions.

OpenSSL access HSM and other hardware devices through its engine functionality. In order to set up a new engine the OpenSSL configuration files must be updated specifying the libp11 and hardware module (here SoftHSM) dynamic libraries location.

OpenSSL on Windows references its default configuration file through the OPENSSL_CONF environment variable. By default OpenSSL installs two identical default configuration files:

  • C:\Program Files\OpenSSL-Win64\bin\cnf\openssl.cnf mimics the Linux distributions one.

  • C:\Program Files\OpenSSL-Win64\bin\openssl.cfg kept for backward compatibility.

Neither of them are loaded by default. In order to direct OpenSSL to load one of them or any other we must set the variable:

cmd> set OPENSSL_CONF=C:\Program Files\OpenSSL-Win64\bin\cnf\openssl.cnf
powershell> $Env:OPENSSL_CONF="C:\Program Files\OpenSSL-Win64\bin\cnf\openssl.cnf"

Once we have hinted OpenSSL the configuration file to use we must modify it to set up the new PKCS#11 engine following the OpenSSL guidelines replacing the binaries path with the proper ones. For example, before any section in the configuration file we introduce:

openssl_conf = openssl_init

at the end of the file we include the engine devoted sections. Note to use POSIX path separator instead of the windows one.

[openssl_init]
    engines = engine_section

[engine_section]
    pkcs11 = pkcs11_section

    [pkcs11_section]
    engine_id = pkcs11
    dynamic_path = C:/Program Files/libp11/src/pkcs11.dll
    MODULE_PATH = C:/Program Files (x86)/SoftHSM2/lib/softhsm2-x64.dll
    init = 0

A proper set up can be verified using OpenSSL command line tool:

openssl engine pkcs11 -t

4.1.3. Colcon installation

colcon is a command line tool based on CMake aimed at building sets of software packages. This section explains how to use it to compile eProsima Fast DDS and its dependencies.

Important

Run colcon within a Visual Studio prompt. To do so, launch a Developer Command Prompt from the search engine.

  1. Install the ROS 2 development tools (colcon and vcstool) by executing the following command:

    pip3 install -U colcon-common-extensions vcstool
    

    and add the path to the vcs executable to the PATH from the Edit the system environment variables control panel.

    Note

    If this fails due to an Environment Error, add the --user flag to the pip3 installation command.

  2. Create a Fast-DDS directory and download the repos file that will be used to install eProsima Fast DDS and its dependencies:

    mkdir ~\Fast-DDS
    cd ~\Fast-DDS
    wget https://raw.githubusercontent.com/eProsima/Fast-DDS/master/fastdds.repos -output fastdds.repos
    mkdir src
    vcs import src --input fastdds.repos
    

    Finally, use colcon to compile all software:

    colcon build --packages-up-to fastdds
    

Note

Being based on CMake, it is possible to pass the CMake configuration options to the colcon build command. For more information on the specific syntax, please refer to the CMake specific arguments page of the colcon manual.

4.1.3.1. Run an application

When running an instance of an application using eProsima Fast DDS, the colcon overlay built in the dedicated Fast-DDS directory must be sourced. There are two possibilities:

  • Every time a new shell is opened, prepare the environment locally by typing the command:

    setup.bat
    
  • Add the sourcing of the colcon overlay permanently, by opening the Edit the system environment variables control panel, and adding ~/Fast-DDS/install/setup.bat to the PATH.

4.1.4. CMake installation

This section explains how to compile eProsima Fast DDS with CMake, either locally or globally.

4.1.4.1. Local installation
  1. Open a command prompt, and create a Fast-DDS directory where to download and build eProsima Fast DDS and its dependencies:

    mkdir %USERPROFILE%\Fast-DDS
    
  2. Clone the following dependencies and compile them using CMake.

    • Fast DDS depends on Foonathan memory. To ease the dependency management, eProsima provides a vendor package Foonathan memory vendor, which downloads and builds a specific revision of Foonathan memory if the library is not found in the system.

      cd %USERPROFILE%\Fast-DDS
      git clone https://github.com/eProsima/foonathan_memory_vendor.git
      cd foonathan_memory_vendor
      mkdir build && cd build
      cmake -DCMAKE_INSTALL_PREFIX=%USERPROFILE%/Fast-DDS/install ..
      cmake --build . --target install
      
    • Fast CDR

      cd %USERPROFILE%\Fast-DDS
      git clone https://github.com/eProsima/Fast-CDR.git
      cd Fast-CDR
      mkdir build && cd build
      cmake -DCMAKE_INSTALL_PREFIX=%USERPROFILE%/Fast-DDS/install ..
      cmake --build . --target install
      
  3. Once all dependencies are installed, install eProsima Fast DDS:

    cd %USERPROFILE%\Fast-DDS
    git clone https://github.com/eProsima/Fast-DDS.git
    cd Fast-DDS
    mkdir build && cd build
    cmake -DCMAKE_INSTALL_PREFIX=%USERPROFILE%/Fast-DDS/install ..
    cmake --build . --target install
    
4.1.4.2. Global installation

To install eProsima Fast DDS system-wide instead of locally, remove the CMAKE_INSTALL_PREFIX flags that appear in the configuration steps of Fast-CDR and Fast-DDS.

Note

By default, eProsima Fast DDS does not compile tests. However, they can be activated by downloading and installing Gtest.

4.1.4.3. Run an application

When running an instance of an application using eProsima Fast DDS, it must be linked with the library where the packages have been installed. This can be done by opening the Edit system environment variables control panel and adding to the PATH the Fast DDS and Fast CDR installation directories:

  • Fast DDS: C:\Program Files\fastdds

  • Fast CDR: C:\Program Files\fastcdr

4.2. Fast DDS Python bindings installation

This section provides the instructions for installing Fast DDS Python bindings in a Windows environment from sources. Fast DDS Python bindings is an extension of Fast DDS which provides access to the Fast DDS API through Python. Therefore, its installation is an extension of the installation of Fast DDS.

Fast DDS Python bindings source code consists on several .i files which will be processed by SWIG. Then C++ files (for connecting C++ and Python) and Python files (Python module for Fast DDS) will be generated.

First of all, the Requirements and Dependencies detailed below need to be met. Afterwards, the user can choose whether to follow either the colcon or the CMake installation instructions.

4.2.1. Requirements

The installation of Fast DDS Python bindings in a Windows environment from sources requires the following tools to be installed in the system:

4.2.1.1. SWIG

SWIG is a development tool that allows connecting programs written in C/C++ with a variety of other programming languages, among them Python. SWIG version lower than 4.2 is required to build Fast DDS Python bindings.

Note

More recent SWIG releases are not yet supported. Please, ensure to be using SWIG 4.0.

4.2.2. Dependencies

Fast DDS Python bindings has the following dependencies, when installed from sources in a Windows environment:

4.2.3. Colcon installation

colcon is a command line tool based on CMake aimed at building sets of software packages. This section explains how to use it to compile Fast DDS Python bindings and its dependencies.

Important

Run colcon within a Visual Studio prompt. To do so, launch a Developer Command Prompt from the search engine.

  1. Install the ROS 2 development tools (colcon and vcstool) by executing the following command:

    pip3 install -U colcon-common-extensions vcstool
    

    and add the path to the vcs executable to the PATH from the Edit the system environment variables control panel.

    Note

    If this fails due to an Environment Error, add the --user flag to the pip3 installation command.

  2. Create a Fast-DDS-python directory and download the repos file that will be used to install Fast DDS Python bindings and its dependencies:

    mkdir ~\Fast-DDS-python
    cd ~\Fast-DDS-python
    wget https://raw.githubusercontent.com/eProsima/Fast-DDS-python/main/fastdds_python.repos
    mkdir src
    vcs import src --input fastdds_python.repos
    
  3. Build the packages:

    colcon build --packages-up-to fastdds_python
    

Note

Being based on CMake, it is possible to pass CMake configuration options to the colcon build command. For more information on the specific syntax, please refer to the CMake specific arguments page of the colcon manual.

4.2.3.1. Run an application

When running an instance of an application using Fast DDS Python bindings, the colcon overlay built in the dedicated Fast-DDS-python directory must be sourced. There are two possibilities:

  • Every time a new shell is opened, prepare the environment locally by typing the command:

    setup.bat
    
  • Add the sourcing of the colcon overlay permanently, by opening the Edit the system environment variables control panel, and adding ~/Fast-DDS/install/setup.bat to the PATH.

4.2.4. CMake installation

This section explains how to compile Fast DDS Python bindings with CMake, either locally or globally.

4.2.4.1. Local installation
  1. Open a command prompt, and create a Fast-DDS-python directory where to download and build Fast DDS Python bindings and its dependencies:

    mkdir %USERPROFILE%\Fast-DDS-python
    
  2. Clone the following dependencies and compile them using CMake.

    • Fast DDS depends on Foonathan memory. To ease the dependency management, eProsima provides a vendor package Foonathan memory vendor, which downloads and builds a specific revision of Foonathan memory if the library is not found in the system.

      cd %USERPROFILE%\Fast-DDS-python
      git clone https://github.com/eProsima/foonathan_memory_vendor.git
      cd foonathan_memory_vendor
      mkdir build && cd build
      cmake -DCMAKE_INSTALL_PREFIX=%USERPROFILE%/Fast-DDS-python/install ..
      cmake --build . --target install
      
    • Fast CDR

      cd %USERPROFILE%\Fast-DDS-python
      git clone https://github.com/eProsima/Fast-CDR.git
      cd Fast-CDR
      mkdir build && cd build
      cmake -DCMAKE_INSTALL_PREFIX=%USERPROFILE%/Fast-DDS-python/install ..
      cmake --build . --target install
      
    • Fast DDS

      cd %USERPROFILE%\Fast-DDS-python
      git clone https://github.com/eProsima/Fast-DDS.git
      cd Fast-DDS
      mkdir build && cd build
      cmake -DCMAKE_INSTALL_PREFIX=%USERPROFILE%/Fast-DDS-python/install ..
      cmake --build . --target install
      
  3. Once all dependencies are installed, install Fast DDS Python bindings:

    cd ~/Fast-DDS-python
    git clone https://github.com/eProsima/Fast-DDS-python.git
    cd Fast-DDS-python
    mkdir build && cd build
    cmake -DCMAKE_INSTALL_PREFIX=%USERPROFILE%/Fast-DDS-python/install ..
    cmake --build . --target install
    
4.2.4.2. Global installation

To install Fast DDS Python bindings system-wide instead of locally, remove all the flags that appear in the configuration steps of Fast-CDR, Fast-DDS and Fast-DDS-python, and change the first in the configuration step of foonathan_memory_vendor to the following:

-DCMAKE_INSTALL_PREFIX=/usr/local/ -DBUILD_SHARED_LIBS=ON

Note

Installation on system directories may need of permissions. Maybe permissions have to be granted through sudo.

sudo cmake --build . --target install
4.2.4.3. Run an application

When running an instance of an application using Fast DDS Python bindings, it must be linked with the library where the packages have been installed. This can be done by opening the Edit system environment variables control panel and adding to the PATH the Fast DDS python, Fast CDR and Fast DDS installation directories:

  • Fast DDS python: C:\Program Files\fastdds_python

  • Fast DDS: C:\Program Files\fastdds

  • Fast CDR: C:\Program Files\fastcdr

4.3. Fast DDS-Gen installation

This section outlines the instructions for installing Fast DDS-Gen in a Windows environment from sources. Fast DDS-Gen is a Java application that generates source code using the data types defined in an IDL file. Please refer to Introduction for more information, and to eProsima products compatibility for the compatibility matrix against Fast DDS versions.

4.3.1. Requirements

Fast DDS-Gen is built using Gradle. Gradle is an open-source build automation tool which requires a Java version to be executed (see Gradle-Java compatibility matrix).

Important

Even though earlier versions of Gradle support Java 8, Fast DDS-Gen stopped supporting Java versions previous to Java 11 since release v2.4.0.

Important

Fast DDS-Gen introduced support for Gradle 7 in release v2.2.0. Gradle 8 is not yet supported.

See also

For further information about Fast DDS-Gen product related versions, please refer to the Library dependencies section.

4.3.1.1. Java JDK

The JDK is a development environment for building applications and components using the Java language. Download and install it following the steps given in the Oracle website.

Note

Fast DDS-Gen supports Java versions from 11 to 19.

4.3.2. Compiling Fast DDS-Gen

In order to compile Fast DDS-Gen, an executable script is included in the repository which will download Gradle temporarily for the compilation step. Please, follow the steps below to build Fast DDS-Gen:

Note

If Fast DDS has already been installed following Colcon installation, skip cloning Fast DDS-Gen’s repository, as it can already be found under the src directory within the colcon workspace.

mkdir -p ~/Fast-DDS/src
cd ~/Fast-DDS/src
git clone --recursive https://github.com/eProsima/Fast-DDS-Gen.git fastddsgen
cd fastddsgen
gradlew.bat assemble

Note

In case that a supported Gradle version is already installed in the system, Fast DDS-Gen can also be built running directly:

gradle assemble
4.3.2.1. Contents

The Fast-DDS-Gen folder contains the following packages:

  • share/fastddsgen, where the generated Java application is.

  • scripts, containing some user friendly scripts.

    Note

    To make these scripts accessible from any directory, add the scripts folder path to the PATH environment variable.

5. Mac OS installation from sources

The instructions for installing both the Fast DDS library and the Fast DDS-Gen generation tool from sources are provided in this page. It is organized as follows:

5.1. Fast DDS library installation

This section describes the instructions for installing eProsima Fast DDS in a Mac OS environment from sources. The following packages will be installed:

  • foonathan_memory_vendor, an STL compatible C++ memory allocator library.

  • fastdds_gen, a Java application that generates source code using the data types defined in an IDL file.

  • fastcdr, a C++ library that serializes according to the standard CDR serialization mechanism.

  • fastdds, the core library of eProsima Fast DDS library.

First of all, the Requirements and Dependencies detailed below need to be met. Afterwards, the user can choose whether to follow either the colcon) or the CMake) installation instructions.

5.1.1. Requirements

The installation of eProsima Fast DDS in a MacOS environment from sources requires the following tools to be installed in the system:

5.1.1.1. Homebrew

Homebrew is a macOS package manager, it is needed to install some of eProsima Fast DDS’s dependencies. To install it open a terminal window and run the following command.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
5.1.1.2. Xcode Command Line Tools

The Xcode command line tools package is separate from Xcode and allows for command line development in mac. The previous step should have installed Xcode CLI, to check the correct installation run the following command:

gcc --version
5.1.1.3. CMake, g++, pip3, wget and git

These packages provide the tools required to install eProsima Fast DDS and its dependencies from command line. Install CMake, pip3 and wget using the Homebrew package manager:

brew install cmake python3 wget
5.1.1.4. Gtest

GTest is a unit testing library for C++. By default, eProsima Fast DDS does not compile tests. It is possible to activate them with the opportune CMake configuration options when calling colcon or CMake. For more details, please refer to the CMake options section. Also add the Gtest repository into the workspace directory.

git clone --branch release-1.11.0 https://github.com/google/googletest src/googletest-distribution
5.1.1.5. XML validation tool

XML validation is a new command introduced to validate the XML profiles against an XSD schema through Fast DDS CLI. That ensures the proper characterization of the entities using the xml profiles.

For more details, please refer to the xml section.

Install the xmlschema dependency to be able to use this optional tool.

5.1.2. Dependencies

eProsima Fast DDS has the following dependencies, when installed from binaries in a Linux environment:

See also

For further information about this Fast DDS version dependencies, as well as for the corresponding versions of other related products, please refer to the Fast DDS Library dependencies section.

5.1.2.1. Asio and TinyXML2 libraries

Asio is a cross-platform C++ library for network and low-level I/O programming, which provides a consistent asynchronous model. TinyXML2 is a simple, small and efficient C++ XML parser. Install these libraries using Homebrew:

brew install asio tinyxml2
5.1.2.2. OpenSSL

OpenSSL is a robust toolkit for the TLS and SSL protocols and a general-purpose cryptography library. Install OpenSSL using Homebrew:

brew install openssl@1.1

5.1.3. Colcon installation

colcon is a command line tool based on CMake aimed at building sets of software packages. This section explains how to use it to compile eProsima Fast DDS and its dependencies.

  1. Install the ROS 2 development tools (colcon and vcstool) by executing the following command:

    pip3 install -U colcon-common-extensions vcstool
    
  2. Create a Fast-DDS directory and download the repos file that will be used to install eProsima Fast DDS and its dependencies:

    mkdir ~/Fast-DDS
    cd ~/Fast-DDS
    wget https://raw.githubusercontent.com/eProsima/Fast-DDS/master/fastdds.repos
    mkdir src
    vcs import src < fastdds.repos
    
  3. Build the packages:

    colcon build --packages-up-to fastdds
    

Note

The --cmake-args option allows to pass the CMake configuration options to the colcon build command. In Mac OS the location of OpenSSL is not found automatically and therefore has to be passed explicitly: --cmake-args -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOPENSSL_LIBRARIES=/usr/local/opt/openssl/lib. This is only required when building with Security. For more information on the specific syntax, please refer to the CMake specific arguments page of the colcon manual.

5.1.3.1. Run an application

When running an instance of an application using eProsima Fast DDS, the colcon overlay built in the dedicated Fast-DDS directory must be sourced. There are two possibilities:

  • Every time a new shell is opened, prepare the environment locally by typing the command:

    source ~/Fast-DDS/install/setup.bash
    
  • Add the sourcing of the colcon overlay permanently to the PATH, by typing the following:

    touch ~/.bash_profile
    echo 'source ~/Fast-DDS/install/setup.bash' >> ~/.bash_profile
    

5.1.4. CMake installation

This section explains how to compile eProsima Fast DDS with CMake, either locally or globally.

5.1.4.1. Local installation
  1. Create a Fast-DDS directory where to download and build eProsima Fast DDS and its dependencies:

    mkdir ~/Fast-DDS
    
  2. Clone the following dependencies and compile them using CMake.

    • Foonathan memory

      cd ~/Fast-DDS
      git clone https://github.com/eProsima/foonathan_memory_vendor.git
      mkdir foonathan_memory_vendor/build
      cd foonathan_memory_vendor/build
      cmake .. -DCMAKE_INSTALL_PREFIX=~/Fast-DDS/install -DBUILD_SHARED_LIBS=ON
      sudo cmake --build . --target install
      
    • Fast CDR

      cd ~/Fast-DDS
      git clone https://github.com/eProsima/Fast-CDR.git
      mkdir Fast-CDR/build
      cd Fast-CDR/build
      cmake ..  -DCMAKE_INSTALL_PREFIX=~/Fast-DDS/install
      sudo cmake --build . --target install
      
  3. Once all dependencies are installed, install eProsima Fast DDS:

    cd ~/Fast-DDS
    git clone https://github.com/eProsima/Fast-DDS.git
    mkdir Fast-DDS/build
    cd Fast-DDS/build
    cmake ..  -DCMAKE_INSTALL_PREFIX=~/Fast-DDS/install -DCMAKE_PREFIX_PATH=~/Fast-DDS/install
    sudo cmake --build . --target install
    

Note

By default, eProsima Fast DDS does not compile tests. However, they can be activated by downloading and installing Gtest.

5.1.4.2. Global installation

To install eProsima Fast DDS system-wide instead of locally, remove all the flags that appear in the configuration steps of Fast-CDR and Fast-DDS, and change the first in the configuration step of foonathan_memory_vendor to the following:

-DCMAKE_INSTALL_PREFIX=/usr/local/ -DBUILD_SHARED_LIBS=ON
5.1.4.3. Run an application

When running an instance of an application using eProsima Fast DDS, it must be linked with the library where the packages have been installed, which in the case of system-wide installation is: /usr/local/lib/ (if local installation is used, adjust for the correct directory). There are two possibilities:

  • Prepare the environment locally by typing the command:

    export LD_LIBRARY_PATH=/usr/local/lib/
    
  • Add it permanently it to the PATH, by typing:

    touch ~/.bash_profile
    echo 'export LD_LIBRARY_PATH=/usr/local/lib/' >> ~/.bash_profile
    

5.2. Fast DDS-Gen installation

This section provides the instructions for installing Fast DDS-Gen in a Mac OS environment from sources. Fast DDS-Gen is a Java application that generates source code using the data types defined in an IDL file. Please refer to Introduction for more information, and to eProsima products compatibility for the compatibility matrix against Fast DDS versions.

5.2.1. Requirements

Fast DDS-Gen is built using Gradle. Gradle is an open-source build automation tool which requires a Java version to be executed (see Gradle-Java compatibility matrix).

Important

Even though earlier versions of Gradle support Java 8, Fast DDS-Gen stopped supporting Java versions previous to Java 11 since release v2.4.0.

Important

Fast DDS-Gen introduced support for Gradle 7 in release v2.2.0. Gradle 8 is not yet supported.

See also

For further information about Fast DDS-Gen product related versions, please refer to the Library dependencies section.

5.2.1.1. Java JDK

The JDK is a development environment for building applications and components using the Java language. Download and install it following the steps given in the Oracle website.

Note

Fast DDS-Gen supports Java versions from 11 to 19.

5.2.2. Compiling Fast DDS-Gen

In order to compile Fast DDS-Gen, an executable script is included in the repository which will download Gradle temporarily for the compilation step. Please, follow the steps below to build Fast DDS-Gen:

Note

If Fast DDS has already been installed following Colcon installation, skip cloning Fast DDS-Gen’s repository, as it can already be found under the src directory within the colcon workspace.

mkdir -p ~/Fast-DDS/src
cd ~/Fast-DDS/src
git clone --recursive https://github.com/eProsima/Fast-DDS-Gen.git fastddsgen
cd fastddsgen
./gradlew assemble

Note

In case that a supported Gradle version is already installed in the system, Fast DDS-Gen can also be built running directly:

gradle assemble
5.2.2.1. Contents

The Fast-DDS-Gen folder contains the following packages:

  • share/fastddsgen, where the generated Java application is.

  • scripts, containing some user friendly scripts.

    Note

    To make these scripts accessible from any shell session and directory, add the scripts folder path to the PATH environment variable using the method described above.

6. QNX 7.1 installation from sources

The instructions for installing Fast DDS library and running examples and tests on QNX 7.1 are provided in this page. It is organized as follows:

6.1. Fast DDS library installation

This section provides the instructions for installing eProsima Fast DDS for QNX 7.1 in a Ubuntu environment from sources. The following packages will be installed:

  • foonathan_memory_vendor, an STL compatible C++ memory allocator library.

  • fastdds_gen, a Java application that generates source code using the data types defined in an IDL file.

  • fastcdr, a C++ library that serializes according to the standard CDR serialization mechanism.

  • fastdds, the core library of eProsima Fast DDS library.

See also

For further information about Fast DDS library dependencies, as well as for the corresponding versions of other related products, please refer to the Fast DDS Library dependencies section.

The Requirements detailed below needs to be met first.

6.1.1. Requirements

Users must be in a Ubuntu environment to cross-compile for QNX 7.1. It is recommended that users use Ubuntu 20.04. The installation of eProsima Fast DDS in a Ubuntu environment from sources requires the following tools to be installed in the system:

6.1.1.1. QNX SDP 7.1

QNX SDP 7.1 is required to be installed in the user’s Ubuntu environment. QNX SDP is QNX’s Software Development Platform which contains tools and files which are needed to cross-compile for QNX.

QNX SDP Installation Guide

For the purpose of these instructions, QNX SDP 7.1 is assumed to be installed at ~/qnx710. If this is not the case, please adjust the paths accordingly.

See also

For further information about Fast DDS build system dependencies regarding QNX 7.1, please refer to the Fast DDS Build system dependencies section.

6.1.1.2. CMake, pip3, git, dos2unix, and automake

These packages provide the tools required to install eProsima Fast DDS and its dependencies from command line.

sudo apt install cmake python3-pip git dos2unix automake

6.1.2. Build and Installation

  1. Open a terminal and clone eProsima Fast DDS:

    git clone https://github.com/eProsima/Fast-DDS.git && cd Fast-DDS
    WORKSPACE=$PWD
    
  2. Initialize git submodules for Asio, Fast-CDR and TinyXML2 and apply QNX patches to them:

    Note

    OpenSSL is already installed in the QNX SDP 7.1.

    cd $WORKSPACE
    
    # Initialize git submodules
    git submodule update --init $WORKSPACE/thirdparty/asio/ $WORKSPACE/thirdparty/fastcdr $WORKSPACE/thirdparty/tinyxml2/
    
    # Apply QNX patch to Asio.
    cd $WORKSPACE/thirdparty/asio
    git apply $WORKSPACE/build_qnx/qnx_patches/asio_qnx.patch
    
    # Apply QNX patch to Fast-CDR.
    cd $WORKSPACE/thirdparty/fastcdr
    git apply $WORKSPACE/build_qnx/qnx_patches/fastcdr_qnx.patch
    
    # Apply QNX patch to TinyXML2.
    # TinyXML2's CMakeLists.txt has CRLF, so use unix2dos to convert the patch to CRLF.
    cd $WORKSPACE/thirdparty/tinyxml2
    unix2dos $WORKSPACE/build_qnx/qnx_patches/tinyxml2_qnx.patch
    git apply $WORKSPACE/build_qnx/qnx_patches/tinyxml2_qnx.patch
    
  3. Get foonathan_memory_vendor:

    cd $WORKSPACE
    git clone https://github.com/eProsima/foonathan_memory_vendor.git
    
  4. Optional: clone GoogleTest and apply QNX patch to it:

    Note

    GoogleTest is required for building Fast-DDS tests.

    cd $WORKSPACE
    git clone https://github.com/google/googletest.git && cd googletest
    git checkout v1.13.0
    git apply $WORKSPACE/build_qnx/qnx_patches/googletest_qnx.patch
    
  5. Source the QNX environment script:

    source ~/qnx710/qnxsdp-env.sh
    
  6. Build and install Fast-DDS and its dependencies:

    Note

    To build examples, set COMPILE_EXAMPLES to ON in $WORKSPACE/build_qnx/common.mk.
    To build tests, set EPROSIMA_BUILD_TESTS to ON in $WORKSPACE/build_qnx/common.mk.

    Note

    All libraries will be installed to $(QNX_TARGET)/$(CPUVARDIR)/usr/lib.
    All examples will be installed to $(QNX_TARGET)/$(CPUVARDIR)/usr/examples.
    All tests will be installed to $(QNX_TARGET)/$(CPUVARDIR)/usr/bin/Fast-DDS_test.
    QNX_TARGET is where the QNX SDP 7.1 installation’s target folder is.
    If QNX SDP 7.1 is installed at ~/qnx710, the QNX_TARGET will be at ~/qnx710/target/qnx7.
    CPUVARDIR is a directory for a specific target architecture e.g. aarch64le and x86_64.
    For example, libraries compiled for an aarch64 target will be at ~/qnx710/target/qnx7/aarch64le/usr/lib assuming QNX SDP 7.1 is installed at ~/qnx710.
    cd $WORKSPACE/build_qnx
    make install -j 4
    

6.2. Run Examples and Tests on a QNX 7.1 Target

Because examples and tests are compiled for QNX, they can only be run on a QNX target, not Ubuntu.

6.2.1. Move Libraries, Examples, and Tests to the QNX Target

  1. Move the built libraries to the QNX target:

    The following steps assume that $(QNX_TARGET) is ~/qnx710/target/qnx7 and that $(CPUVARDIR) is aarch64le. Adjust the values if this is not the case.

    # Move Fast-CDR library to the QNX target
    scp ~/qnx710/target/qnx7/aarch64le/usr/lib/libfastcdr.so* root@<target-ip-address>:/usr/lib
    
    # Move Fast-DDS library to the QNX target
    scp ~/qnx710/target/qnx7/aarch64le/usr/lib/libfastdds.so* root@<target-ip-address>:/usr/lib
    
    # Move Foonathan Memory library to the QNX target
    scp ~/qnx710/target/qnx7/aarch64le/usr/lib/libfoonathan_memory* root@<target-ip-address>:/usr/lib
    
    # Move TinyXML2 library to the QNX target
    scp ~/qnx710/target/qnx7/aarch64le/usr/lib/libtinyxml2.so* root@<target-ip-address>:/usr/lib
    
    # Move GoogleTest library to the QNX target
    scp ~/qnx710/target/qnx7/aarch64le/usr/lib/libgtest* root@<target-ip-address>:/usr/lib
    scp ~/qnx710/target/qnx7/aarch64le/usr/lib/libgmock* root@<target-ip-address>:/usr/lib
    
  2. Move examples and tests to the QNX target:

    # Move Fast-CDR library to the QNX target
    scp -r ~/qnx710/target/qnx7/aarch64le/usr/examples root@<target-ip-address>:/var
    
    # Move Fast-DDS library to the QNX target
    scp -r ~/qnx710/target/qnx7/aarch64le/usr/bin/Fast-DDS_test root@<target-ip-address>:/var
    

6.2.2. Run Hello World

  1. Open a terminal and run a subscriber:

    # ssh into the QNX target
    ssh root@<target-ip-address>
    
    # Run a subscriber
    /var/examples/cpp/hello_world/bin/hello_world subscriber
    
  2. Open another terminal and run a publisher:

    # ssh into the QNX target
    ssh root@<target-ip-address>
    
    # Run a publisher
    /var/examples/cpp/hello_world/bin/hello_world publisher
    

The following output will be shown in the subscriber terminal:

Starting
Subscriber running. Please press enter to stop the Subscriber
Subscriber matched.
Message HelloWorld 1 RECEIVED
Message HelloWorld 2 RECEIVED
Message HelloWorld 3 RECEIVED
Message HelloWorld 4 RECEIVED
Message HelloWorld 5 RECEIVED
Message HelloWorld 6 RECEIVED
Message HelloWorld 7 RECEIVED
Message HelloWorld 8 RECEIVED
Message HelloWorld 9 RECEIVED
Message HelloWorld 10 RECEIVED
Subscriber unmatched.

The following output will be shown for the publisher:

Starting
Publisher running 10 samples.
Publisher matched.
Message: HelloWorld with index: 1 SENT
Message: HelloWorld with index: 2 SENT
Message: HelloWorld with index: 3 SENT
Message: HelloWorld with index: 4 SENT
Message: HelloWorld with index: 5 SENT
Message: HelloWorld with index: 6 SENT
Message: HelloWorld with index: 7 SENT
Message: HelloWorld with index: 8 SENT
Message: HelloWorld with index: 9 SENT
Message: HelloWorld with index: 10 SENT

6.2.3. Run a Test

Because test binaries compiled for QNX cannot be run on Ubuntu, test binaries must be run on a target which is running QNX.

# ssh into the QNX target
ssh root@<target-ip-address>

# Run a test
cd /var/Fast-DDS_test/unittest/dds/core/entity
./EntityTests

The following test output for EntityTests will be shown:

[==========] Running 5 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 5 tests from EntityTests
[ RUN      ] EntityTests.entity_constructor
[       OK ] EntityTests.entity_constructor (0 ms)
[ RUN      ] EntityTests.entity_enable
[       OK ] EntityTests.entity_enable (0 ms)
[ RUN      ] EntityTests.entity_get_instance_handle
[       OK ] EntityTests.entity_get_instance_handle (0 ms)
[ RUN      ] EntityTests.entity_equal_operator
[       OK ] EntityTests.entity_equal_operator (0 ms)
[ RUN      ] EntityTests.get_statuscondition
[       OK ] EntityTests.get_statuscondition (0 ms)
[----------] 5 tests from EntityTests (0 ms total)

[----------] Global test environment tear-down
[==========] 5 tests from 1 test suite ran. (0 ms total)
[  PASSED  ] 5 tests.

7. CMake options

eProsima Fast DDS provides numerous CMake options for changing the behavior and configuration of Fast DDS. These options allow the user to enable/disable certain Fast DDS settings by defining these options to ON/OFF at the CMake execution. This section is structured as follows: first, the CMake options for the general configuration of Fast DDS are described; then, the options related to the third party libraries are presented; finally, the possible options for the building of Fast DDS tests are defined.

7.1. General options

The Fast DDS CMake options for configuring general settings are shown below, together with their description and dependency on other options.

Option

Description

Possible values

Default

EPROSIMA_INSTALLER

Creates a build for Windows binary installers. Specifically it adds to the list of
components to install (CPACK_COMPONENTS_ALL) the libraries corresponding
to the Microsoft Visual C++ compiler (MSVC). Setting EPROSIMA_INSTALLER
to ON has the following effects on other options:

  • EPROSIMA_BUILD is set to ON.

  • BUILD_DOCUMENTATION is set to ON.

  • INSTALL_EXAMPLES is set to ON.

ON OFF

OFF

EPROSIMA_BUILD

Activates internal Fast DDS builds. It is set to ON if EPROSIMA_INSTALLER is
ON. Setting EPROSIMA_BUILD to ON has the following effects on other
options:

  • INTERNAL_DEBUG is set to ON.

  • COMPILE_EXAMPLES is set to ON if EPROSIMA_INSTALLER is OFF.

  • THIRDPARTY_fastcdr is set to ON if it was not set to FORCE.

  • THIRDPARTY_Asio is set to ON if it was not set to FORCE.

  • THIRDPARTY_TinyXML2 is set to ON if it was not set to FORCE.

  • THIRDPARTY_android-ifaddrs is set to ON if it was not set to FORCE.

  • EPROSIMA_BUILD_TESTS is set to ON if EPROSIMA_INSTALLER is OFF.

ON OFF

OFF

BUILD_SHARED_LIBS

Builds internal libraries as shared libraries, i.e. cause add_library() CMake
function to create shared libraries if on. All libraries are built shared unless the
library was explicitly added as a static library.

ON OFF

ON

SECURITY

Activates the Fast DDS security module. Please refer to Security for more
information on security module.

ON OFF

OFF

NO_TLS

Disables Transport Layer Security (TLS) Support. Please refer to TLS over TCP
for more information on Fast DDS TLS configuration.

ON OFF

OFF

SHM_TRANSPORT_DEFAULT

Adds Shared Memory transport (SHM) to the default transports. Please refer to
SHM section for more information on Fast DDS SHM transport.

ON OFF

ON

FASTDDS_STATISTICS

Enables the Fast DDS Statistics module. Please refer to Statistics Module for
more information on this module.

ON OFF

ON

COMPILE_EXAMPLES

Builds the Fast DDS examples. It is set to ON if EPROSIMA_BUILD is ON and
EPROSIMA_INSTALLER is OFF. These examples can be found in the
eProsima Fast DDS GitHub repository.

ON OFF

OFF

INSTALL_EXAMPLES

Installs the Fast DDS examples, i.e. adds the Fast DDS examples to the list of
components to install (CPACK_COMPONENTS_ALL). It is set to ON if
EPROSIMA_INSTALLER is ON.

ON OFF

OFF

BUILD_DOCUMENTATION

Uses doxygen to create the Fast DDS API reference documentation. It is set to
ON if EPROSIMA_INSTALLER is ON or if CHECK_DOCUMENTATION is ON.

ON OFF

OFF

CHECK_DOCUMENTATION

Downloads Fast DDS documentation from Read the Docs media servers. The
documentation files are extracted in the doc/manual directory, updating
any previous version already downloaded.
If CHECK_DOCUMENTATION is ON, BUILD_DOCUMENTATION is set to ON.

ON OFF

OFF

STRICT_REALTIME

Enables a strict real-time behaviour. Please refer to the Real-Time Use Case for
more information on Fast DDS real-time configuration.

ON OFF

OFF

SQLITE3_SUPPORT

Builds the SQLITE3 Plugin, which enables the TRANSIENT_DURABILITY_QOS
and PERSISTENT_DURABILITY_QOS options for the DurabilityQosPolicyKind
and therefore the Persistence Service.

ON OFF

ON

APPEND_PROJECT_NAME_TO_INCLUDEDIR

When ON headers are installed to a path ending with a folder called fastdds.
This avoids include directory search order issues when overriding this package
from a merged catkin, ament, or colcon workspace.

ON OFF

OFF

USE_THIRDPARTY_SHARED_MUTEX

When ON a custom implementation of shared_mutex is used instead of the STL one.
The C++ Standard has not yet (C++20) imposed any requirements on shared_mutex
priority policies implementation, as POSIX does, thus each platform made its own choices:

  • Windows & Boost defaults to PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP.

  • Linux & Mac defaults to PTHREAD_RWLOCK_PREFER_READER_NP.

Fast-DDS requires the use of PTHREAD_RWLOCK_PREFER_READER_NP which is the one enforced
in its deadlock prevention logic.

Fast-DDS will test the framework STL implementation (if available) and will only use it if
it enforces PTHREAD_RWLOCK_PREFER_READER_NP. Otherwise it will automatically fallback to
a custom implementation.

This flag will enforce the use of the custom implementation in all cases.

Note that setting the flag OFF will not prevent the use of the custom implementation
in those frameworks that default to PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP.

This flag prevents spurious thread sanitizer reports on GCC/Clang STL implementations.

ON OFF

OFF (Linux & Mac), ON (Windows)

SANITIZER

Adds run-time instrumentation to the code. Supported options are:

  • Thread enables Thread Sanitizer.

  • Address enables Address Sanitizer.

OFF
Address
Thread

OFF

7.2. Log options

Fast DDS uses its own configurable Log module with different verbosity levels. Please, refer to Logging section for more information.

This module can be configured using Fast DDS CMake arguments regarding the following options.

Option

Description

Possible values

Default

LOG_CONSUMER_DEFAULT

Selects the default log consumer for the logging module.
AUTO has the same behavior as STDOUTERR.
For more information, please refer to Log consumers.

AUTO STDOUT
STDOUTERR

AUTO

LOG_NO_INFO

Deactivates Info Log level.
If Fast DDS is built in debug mode for Single-Config generators,
the default value will be OFF.

ON OFF

ON

FASTDDS_ENFORCE_LOG_INFO

Enables Info Log level even on non Debug configurations.
This option only takes action if LOG_NO_INFO is set to OFF
(see Disable Logging Module).
Mind that this may entail a significant performance hit.

ON OFF

OFF

LOG_NO_WARNING

Deactivates Warning Log level.

ON OFF

OFF

LOG_NO_ERROR

Deactivates Error Log level.

ON OFF

OFF

INTERNAL_DEBUG

Activates compilation of log messages
(See Disable Logging Module).
Moreover, INTERNAL_DEBUG is set to ON if
EPROSIMA_BUILD is ON.

ON OFF

OFF

ENABLE_OLD_LOG_MACROS

Enable old log macros
(See Old Log macros disable).

ON OFF

ON

7.3. Third-party libraries options

Fast DDS relies on the eProsima FastCDR library for serialization mechanisms. Moreover, Fast DDS requires two external dependencies for its proper operation: Asio and TinyXML2. Asio is a cross-platform C++ library for network and low-level I/O programming, while TinyXML2 parses the XML profile files, so Fast DDS can use them (see XML profiles). These three libraries (eProsima FastCDR, Asio and TinyXML2) can be installed by the user, or downloaded on the Fast DDS build. In the latter case, they are referred to as Fast DDS internal third-party libraries. This can be done by setting either THIRDPARTY or EPROSIMA_BUILD to ON.

These libraries can also be configured using Fast DDS CMake options.

Option

Description

Possible values

Default

THIRDPARTY_fastcdr

ON activates the use of the internal Fast CDR third-party library if it is not
found elsewhere in the system.
FORCE activates the use of the internal Fast CDR third-party library
regardless of whether it can be found elsewhere in the system.
OFF deactivates the use of the internal Fast CDR third-party library.
If it is not set to FORCE, it is set to ON if EPROSIMA_BUILD is ON.

ON OFF FORCE

OFF

THIRDPARTY_Asio

ON activates the use of the internal Asio third-party library if it is not
found elsewhere in the system.
FORCE activates the use of the internal Asio third-party library
regardless of whether it can be found elsewhere in the system.
OFF deactivates the use of the internal Asio third-party library.
If it is not set to FORCE, it is set to ON if EPROSIMA_BUILD is ON.

ON OFF FORCE

OFF

THIRDPARTY_TinyXML2

ON activates the use of the internal TinyXML2 third-party library if it is not
found elsewhere in the system.
FORCE activates the use of the internal TinyXML2 third-party library
regardless of whether it can be found elsewhere in the system.
OFF deactivates the use of the internal TinyXML2 third-party library.
If it is not set to FORCE, it is set to ON if EPROSIMA_BUILD is ON.

ON OFF FORCE

OFF

THIRDPARTY_android-ifaddrs

android-ifaddrs is an implementation of getifaddrs() for Android.
Only used if ANDROID is 1.
ON activates the use of the internal android-ifaddrs third-party library if it is not
found elsewhere in the system.
FORCE activates the use of the internal android-ifaddrs third-party library
regardless of whether it can be found elsewhere in the system.
OFF deactivates the use of the internal android-ifaddrs third-party library.
If it is not set to FORCE, it is set to ON if EPROSIMA_BUILD is ON.

ON OFF FORCE

OFF

THIRDPARTY

Unless they are otherwise specified, sets value of all third-party
git submodules THIRDPARTY_fastcdr, THIRDPARTY_Asio,
THIRDPARTY_TinyXML2, and THIRDPARTY_android-ifaddrs.

ON OFF FORCE

OFF

THIRDPARTY_UPDATE

Activates the update of all third-party git submodules.

ON OFF

ON

Note

ANDROID is a CMake environment variable that is set to 1 if the target system (CMAKE_SYSTEM_NAME) is Android.

7.4. Test options

eProsima Fast DDS comes with a full set of tests for continuous integration. The types of tests are: unit tests, black-box tests, performance tests, profiling tests, and XTypes tests. The building and execution of these tests is specified by the Fast DDS CMake options shown in the table below.

Option

Description

Possible values

Default

FASTDDS_PIM_API_TESTS

Enables the building of black-box tests for the verification of DDS communications
using the Fast DDS DDS-layer API.

ON OFF

OFF

FASTDDS_EXAMPLE_TESTS

Enables the building of example tests for the verification of the Fast DDS examples

ON OFF

OFF

PERFORMANCE_TESTS

Activates the building of performance tests, except for the video test, which requires
both PERFORMANCE_TESTS and VIDEO_TESTS to be set to ON.

ON OFF

OFF

PROFILING_TESTS

Activates the building of profiling tests using Valgrind.

ON OFF

OFF

EPROSIMA_BUILD_TESTS

Activates the building of black-box, unit, xtypes, RTPS communication and
DDS communication tests. It is set to ON if EPROSIMA_BUILD is ON and
EPROSIMA_INSTALLER is OFF.

ON OFF

OFF

VIDEO_TESTS

If PERFORMANCE_TESTS is ON, it will activate the building of video performance tests.

ON OFF

OFF

DISABLE_UDPV6_TESTS

Disables UDPv6 tests.

ON OFF

OFF

INSTALL_ANDROID_TESTS

Android cross-compilation only. Marks the tests for installation on the
connected device/emulator.

ON OFF

OFF

ANDROID_TESTING_ROOT

Android cross-compilation only. Path on the Android device/emulator to
use for installing and running the tests.

Valid Unix filesystem path string

""

1. Getting Started

This section defines the concepts of DDS and RTPS. It also provides a step-by-step tutorial on how to write a simple Fast DDS (formerly Fast RTPS) publish/subscribe application.

1.1. What is DDS?

The Data Distribution Service (DDS) is a data-centric communication protocol used for distributed software application communications. It describes the communications Application Programming Interfaces (APIs) and Communication Semantics that enable communication between data providers and data consumers.

Since it is a Data-Centric Publish Subscribe (DCPS) model, three key application entities are defined in its implementation: publication entities, which define the information-generating objects and their properties; subscription entities, which define the information-consuming objects and their properties; and configuration entities that define the types of information that are transmitted as topics, and create the publisher and subscriber with its Quality of Service (QoS) properties, ensuring the correct performance of the above entities.

DDS uses QoS to define the behavioral characteristics of DDS Entities. QoS are comprised of individual QoS policies (objects of type deriving from QoSPolicy). These are described in Policy.

1.1.1. The DCPS conceptual model

In the DCPS model, four basic elements are defined for the development of a system of communicating applications.

  • Publisher. It is the DCPS entity in charge of the creation and configuration of the DataWriters it implements. The DataWriter is the entity in charge of the actual publication of the messages. Each one will have an assigned Topic under which the messages are published. See Publisher for further details.

  • Subscriber. It is the DCPS Entity in charge of receiving the data published under the topics to which it subscribes. It serves one or more DataReader objects, which are responsible for communicating the availability of new data to the application. See Subscriber for further details.

  • Topic. It is the entity that binds publications and subscriptions. It is unique within a DDS domain. Through the TopicDescription, it allows the uniformity of data types of publications and subscriptions. See Topic for further details.

  • Domain. This is the concept used to link all publishers and subscribers, belonging to one or more applications, which exchange data under different topics. These individual applications that participate in a domain are called DomainParticipant. The DDS Domain is identified by a domain ID. The DomainParticipant defines the domain ID to specify the DDS domain to which it belongs. Two DomainParticipants with different IDs are not aware of each other’s presence in the network. Hence, several communication channels can be created. This is applied in scenarios where several DDS applications are involved, with their respective DomainParticipants communicating with each other, but these applications must not interfere. The DomainParticipant acts as a container for other DCPS Entities, acts as a factory for Publisher, Subscriber and Topic Entities, and provides administrative services in the domain. See Domain for further details.

These elements are shown in the figure below.

_images/dds_domain.svg

DCPS model entities in the DDS Domain.

1.2. What is RTPS?

The Real-Time Publish Subscribe (RTPS) protocol, developed to support DDS applications, is a publication-subscription communication middleware over best-effort transports such as UDP/IP. Furthermore, Fast DDS provides support for TCP and Shared Memory (SHM) transports.

It is designed to support both unicast and multicast communications.

At the top of RTPS, inherited from DDS, the Domain can be found, which defines a separate plane of communication. Several domains can coexist at the same time independently. A domain contains any number of RTPSParticipants, that is, elements capable of sending and receiving data. To do this, the RTPSParticipants use their Endpoints:

  • RTPSWriter: Endpoint able to send data.

  • RTPSReader: Endpoint able to receive data.

A RTPSParticipant can have any number of writer and reader endpoints.

_images/rtps_domain.svg

RTPS high-level architecture

Communication revolves around Topics, which define and label the data being exchanged. The topics do not belong to a specific participant. The participant, through the RTPSWriters, makes changes in the data published under a topic, and through the RTPSReaders receives the data associated with the topics to which it subscribes. The communication unit is called Change, which represents an update in the data that is written under a Topic. RTPSReaders/RTPSWriters register these changes on their History, a data structure that serves as a cache for recent changes.

In the default configuration of eProsima Fast DDS, when you publish a change through a RTPSWriter endpoint, the following steps happen behind the scenes:

  1. The change is added to the RTPSWriter’s history cache.

  2. The RTPSWriter sends the change to any RTPSReaders it knows about.

  3. After receiving data, RTPSReaders update their history cache with the new change.

However, Fast DDS supports numerous configurations that allow you to change the behavior of RTPSWriters/RTPSReaders. A modification in the default configuration of the RTPS entities implies a change in the data exchange flow between RTPSWriters and RTPSReaders. Moreover, by choosing Quality of Service (QoS) policies, you can affect how these history caches are managed in several ways, but the communication loop remains the same. You can continue reading section RTPS Layer to learn more about the implementation of the RTPS protocol in Fast DDS.

1.3. Writing a simple C++ publisher and subscriber application

This section details how to create a simple Fast DDS application with a publisher and a subscriber using C++ API step by step. It is also possible to self-generate a similar example to the one implemented in this section by using the eProsima Fast DDS-Gen tool. This additional approach is explained in Building a publish/subscribe application.

1.3.1. Background

DDS is a data-centric communications middleware that implements the DCPS model. This model is based on the development of a publisher, a data generating element; and a subscriber, a data consuming element. These entities communicate by means of the topic, an element that binds both DDS entities. Publishers generate information under a topic and subscribers subscribe to this same topic to receive information.

1.3.2. Prerequisites

First of all, you need to follow the steps outlined in the Installation Manual for the installation of eProsima Fast DDS and all its dependencies. You also need to have completed the steps outlined in the Installation Manual for the installation of the eProsima Fast DDS-Gen tool. Moreover, all the commands provided in this tutorial are outlined for a Linux environment.

1.3.3. Create the application workspace

The application workspace will have the following structure at the end of the project. Files build/DDSHelloWorldPublisher and build/DDSHelloWorldSubscriber are the Publisher application and Subscriber application respectively.

.
└── workspace_DDSHelloWorld
    ├── build
    │   ├── CMakeCache.txt
    │   ├── CMakeFiles
    │   ├── cmake_install.cmake
    │   ├── DDSHelloWorldPublisher
    │   ├── DDSHelloWorldSubscriber
    │   └── Makefile
    ├── CMakeLists.txt
    └── src
        ├── HelloWorld.hpp
        ├── HelloWorld.idl
        ├── HelloWorldCdrAux.hpp
        ├── HelloWorldCdrAux.ipp
        ├── HelloWorldPublisher.cpp
        ├── HelloWorldPubSubTypes.cxx
        ├── HelloWorldPubSubTypes.h
        ├── HelloWorldSubscriber.cpp
        ├── HelloWorldTypeObjectSupport.cxx
        └── HelloWorldTypeObjectSupport.hpp

Let’s create the directory tree first.

mkdir workspace_DDSHelloWorld && cd workspace_DDSHelloWorld
mkdir src build

1.3.4. Import linked libraries and its dependencies

The DDS application requires the Fast DDS and Fast CDR libraries. Depending on the installation procedure followed the process of making these libraries available for our DDS application will be slightly different.

1.3.4.1. Installation from binaries and manual installation

If we have followed the installation from binaries or the manual installation, these libraries are already accessible from the workspace. On Linux, the header files can be found in directories /usr/include/fastdds/ and /usr/include/fastcdr/ for Fast DDS and Fast CDR respectively. The compiled libraries of both can be found in the directory /usr/lib/.

1.3.4.2. Colcon installation

From a Colcon installation there are several ways to import the libraries. If the libraries need to be available just for the current session, run the following command.

source <path/to/Fast-DDS/workspace>/install/setup.bash

They can be made accessible from any session by adding the Fast DDS installation directory to your $PATH variable in the shell configuration files for the current user running the following command.

echo 'source <path/to/Fast-DDS/workspace>/install/setup.bash' >> ~/.bashrc

This will set up the environment after each of this user’s logins.

1.3.5. Configure the CMake project

We will use the CMake tool to manage the building of the project. With your preferred text editor, create a new file called CMakeLists.txt and copy and paste the following code snippet. Save this file in the root directory of your workspace. If you have followed these steps, it should be workspace_DDSHelloWorld.

cmake_minimum_required(VERSION 3.20)

project(DDSHelloWorld)

# Find requirements
if(NOT fastcdr_FOUND)
    find_package(fastcdr 2 REQUIRED)
endif()

if(NOT fastdds_FOUND)
    find_package(fastdds 3 REQUIRED)
endif()

# Set C++11
include(CheckCXXCompilerFlag)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG OR
        CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    check_cxx_compiler_flag(-std=c++11 SUPPORTS_CXX11)
    if(SUPPORTS_CXX11)
        add_compile_options(-std=c++11)
    else()
        message(FATAL_ERROR "Compiler doesn't support C++11")
    endif()
endif()

message(STATUS "Configuring HelloWorld publisher/subscriber example...")
file(GLOB DDS_HELLOWORLD_SOURCES_CXX "src/*.cxx")

In each section we will complete this file to include the specific generated files.

1.3.6. Build the topic data type

eProsima Fast DDS-Gen is a Java application that generates source code using the data types defined in an Interface Description Language (IDL) file. This application can do two different things:

  1. Generate C++ definitions for your custom topic.

  2. Generate a functional example that uses your topic data.

It will be the former that will be followed in this tutorial. To see an example of application of the latter you can check this other example. See Introduction for further details. For this project, we will use the Fast DDS-Gen application to define the data type of the messages that will be sent by the publishers and received by the subscribers.

In the workspace directory, execute the following commands:

cd src && touch HelloWorld.idl

This creates the HelloWorld.idl file in the src directory. Open the file in a text editor and copy and paste the following snippet of code.

struct HelloWorld
{
    unsigned long index;
    string message;
};

By doing this we have defined the HelloWorld data type, which has two elements: an index of type uint32_t and a message of type std::string. All that remains is to generate the source code that implements this data type in C++11. To do this, run the following command from the src directory.

<path/to/Fast DDS-Gen>/scripts/fastddsgen HelloWorld.idl

This must have generated the following files:

  • HelloWorld.hpp: HelloWorld type definition.

  • HelloWorldPubSubTypes.cxx: Interface used by Fast DDS to support HelloWorld type.

  • HelloWorldPubSubTypes.h: Header file for HelloWorldPubSubTypes.cxx.

  • HelloWorldCdrAux.ipp: Serialization and Deserialization code for the HelloWorld type.

  • HelloWorldCdrAux.hpp: Header file for HelloWorldCdrAux.ipp.

  • HelloWorldTypeObjectSupport.cxx: TypeObject representation registration code.

  • HelloWorldTypeObjectSupport.hpp: Header file for HelloWorldTypeObjectSupport.cxx.

1.3.7. Write the Fast DDS publisher

From the src directory in the workspace, run the following command to download the HelloWorldPublisher.cpp file.

wget -O HelloWorldPublisher.cpp \
    https://raw.githubusercontent.com/eProsima/Fast-RTPS-docs/master/code/Examples/C++/DDSHelloWorld/src/HelloWorldPublisher.cpp

This is the C++ source code for the publisher application. It is going to send 10 publications under the topic HelloWorldTopic.

  1// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
  2//
  3// Licensed under the Apache License, Version 2.0 (the "License");
  4// you may not use this file except in compliance with the License.
  5// You may obtain a copy of the License at
  6//
  7//     http://www.apache.org/licenses/LICENSE-2.0
  8//
  9// Unless required by applicable law or agreed to in writing, software
 10// distributed under the License is distributed on an "AS IS" BASIS,
 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12// See the License for the specific language governing permissions and
 13// limitations under the License.
 14
 15/**
 16 * @file HelloWorldPublisher.cpp
 17 *
 18 */
 19
 20#include "HelloWorldPubSubTypes.hpp"
 21
 22#include <chrono>
 23#include <thread>
 24
 25#include <fastdds/dds/domain/DomainParticipant.hpp>
 26#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
 27#include <fastdds/dds/publisher/DataWriter.hpp>
 28#include <fastdds/dds/publisher/DataWriterListener.hpp>
 29#include <fastdds/dds/publisher/Publisher.hpp>
 30#include <fastdds/dds/topic/TypeSupport.hpp>
 31
 32using namespace eprosima::fastdds::dds;
 33
 34class HelloWorldPublisher
 35{
 36private:
 37
 38    HelloWorld hello_;
 39
 40    DomainParticipant* participant_;
 41
 42    Publisher* publisher_;
 43
 44    Topic* topic_;
 45
 46    DataWriter* writer_;
 47
 48    TypeSupport type_;
 49
 50    class PubListener : public DataWriterListener
 51    {
 52    public:
 53
 54        PubListener()
 55            : matched_(0)
 56        {
 57        }
 58
 59        ~PubListener() override
 60        {
 61        }
 62
 63        void on_publication_matched(
 64                DataWriter*,
 65                const PublicationMatchedStatus& info) override
 66        {
 67            if (info.current_count_change == 1)
 68            {
 69                matched_ = info.total_count;
 70                std::cout << "Publisher matched." << std::endl;
 71            }
 72            else if (info.current_count_change == -1)
 73            {
 74                matched_ = info.total_count;
 75                std::cout << "Publisher unmatched." << std::endl;
 76            }
 77            else
 78            {
 79                std::cout << info.current_count_change
 80                        << " is not a valid value for PublicationMatchedStatus current count change." << std::endl;
 81            }
 82        }
 83
 84        std::atomic_int matched_;
 85
 86    } listener_;
 87
 88public:
 89
 90    HelloWorldPublisher()
 91        : participant_(nullptr)
 92        , publisher_(nullptr)
 93        , topic_(nullptr)
 94        , writer_(nullptr)
 95        , type_(new HelloWorldPubSubType())
 96    {
 97    }
 98
 99    virtual ~HelloWorldPublisher()
100    {
101        if (writer_ != nullptr)
102        {
103            publisher_->delete_datawriter(writer_);
104        }
105        if (publisher_ != nullptr)
106        {
107            participant_->delete_publisher(publisher_);
108        }
109        if (topic_ != nullptr)
110        {
111            participant_->delete_topic(topic_);
112        }
113        DomainParticipantFactory::get_instance()->delete_participant(participant_);
114    }
115
116    //!Initialize the publisher
117    bool init()
118    {
119        hello_.index(0);
120        hello_.message("HelloWorld");
121
122        DomainParticipantQos participantQos;
123        participantQos.name("Participant_publisher");
124        participant_ = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);
125
126        if (participant_ == nullptr)
127        {
128            return false;
129        }
130
131        // Register the Type
132        type_.register_type(participant_);
133
134        // Create the publications Topic
135        topic_ = participant_->create_topic("HelloWorldTopic", "HelloWorld", TOPIC_QOS_DEFAULT);
136
137        if (topic_ == nullptr)
138        {
139            return false;
140        }
141
142        // Create the Publisher
143        publisher_ = participant_->create_publisher(PUBLISHER_QOS_DEFAULT, nullptr);
144
145        if (publisher_ == nullptr)
146        {
147            return false;
148        }
149
150        // Create the DataWriter
151        writer_ = publisher_->create_datawriter(topic_, DATAWRITER_QOS_DEFAULT, &listener_);
152
153        if (writer_ == nullptr)
154        {
155            return false;
156        }
157        return true;
158    }
159
160    //!Send a publication
161    bool publish()
162    {
163        if (listener_.matched_ > 0)
164        {
165            hello_.index(hello_.index() + 1);
166            writer_->write(&hello_);
167            return true;
168        }
169        return false;
170    }
171
172    //!Run the Publisher
173    void run(
174            uint32_t samples)
175    {
176        uint32_t samples_sent = 0;
177        while (samples_sent < samples)
178        {
179            if (publish())
180            {
181                samples_sent++;
182                std::cout << "Message: " << hello_.message() << " with index: " << hello_.index()
183                            << " SENT" << std::endl;
184            }
185            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
186        }
187    }
188};
189
190int main(
191        int argc,
192        char** argv)
193{
194    std::cout << "Starting publisher." << std::endl;
195    uint32_t samples = 10;
196
197    HelloWorldPublisher* mypub = new HelloWorldPublisher();
198    if(mypub->init())
199    {
200        mypub->run(samples);
201    }
202
203    delete mypub;
204    return 0;
205}
1.3.7.1. Examining the code

At the beginning of the file we have a Doxygen style comment block with the @file field that tells us the name of the file.

/**
 * @file HelloWorldPublisher.cpp
 *
 */

Below are the includes of the C++ headers. The first one includes the HelloWorldPubSubTypes.h file with the serialization and deserialization functions of the data type that we have defined in the previous section.

#include "HelloWorldPubSubTypes.hpp"

The next block includes the C++ header files that allow the use of the Fast DDS API.

  • DomainParticipantFactory. Allows for the creation and destruction of DomainParticipant objects.

  • DomainParticipant. Acts as a container for all other Entity objects and as a factory for the Publisher, Subscriber, and Topic objects.

  • TypeSupport. Provides the participant with the functions to serialize, deserialize and get the key of a specific data type.

  • Publisher. It is the object responsible for the creation of DataWriters.

  • DataWriter. Allows the application to set the value of the data to be published under a given Topic.

  • DataWriterListener. Allows the redefinition of the functions of the DataWriterListener.

#include <chrono>
#include <thread>

#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/DataWriterListener.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>

Next, we define the namespace that contains the eProsima Fast DDS classes and functions that we are going to use in our application.

using namespace eprosima::fastdds::dds;

The next line creates the HelloWorldPublisher class that implements a publisher.

class HelloWorldPublisher

Continuing with the private data members of the class, the hello_ data member is defined as an object of the HelloWorld class that defines the data type we created with the IDL file. Next, the private data members corresponding to the participant, publisher, topic, DataWriter and data type are defined. The type_ object of the TypeSupport class is the object that will be used to register the topic data type in the DomainParticipant.

private:

    HelloWorld hello_;

    DomainParticipant* participant_;

    Publisher* publisher_;

    Topic* topic_;

    DataWriter* writer_;

    TypeSupport type_;

Then, the PubListener class is defined by inheriting from the DataWriterListener class. This class overrides the default DataWriter listener callbacks, which allows the execution of routines in case of an event. The overridden callback on_publication_matched() allows the definition of a series of actions when a new DataReader is detected listening to the topic under which the DataWriter is publishing. The info.current_count_change detects these changes of DataReaders that are matched to the DataWriter. This is a member in the MatchedStatus structure that allows tracking changes in the status of subscriptions. Finally, the listener_ object of the class is defined as an instance of PubListener.

class PubListener : public DataWriterListener
{
public:

    PubListener()
        : matched_(0)
    {
    }

    ~PubListener() override
    {
    }

    void on_publication_matched(
            DataWriter*,
            const PublicationMatchedStatus& info) override
    {
        if (info.current_count_change == 1)
        {
            matched_ = info.total_count;
            std::cout << "Publisher matched." << std::endl;
        }
        else if (info.current_count_change == -1)
        {
            matched_ = info.total_count;
            std::cout << "Publisher unmatched." << std::endl;
        }
        else
        {
            std::cout << info.current_count_change
                    << " is not a valid value for PublicationMatchedStatus current count change." << std::endl;
        }
    }

    std::atomic_int matched_;

} listener_;

The public constructor and destructor of the HelloWorldPublisher class are defined below. The constructor initializes the private data members of the class to nullptr, with the exception of the TypeSupport object, that is initialized as an instance of the HelloWorldPubSubType class. The class destructor removes these data members and thus cleans the system memory.

HelloWorldPublisher()
    : participant_(nullptr)
    , publisher_(nullptr)
    , topic_(nullptr)
    , writer_(nullptr)
    , type_(new HelloWorldPubSubType())
{
}

virtual ~HelloWorldPublisher()
{
    if (writer_ != nullptr)
    {
        publisher_->delete_datawriter(writer_);
    }
    if (publisher_ != nullptr)
    {
        participant_->delete_publisher(publisher_);
    }
    if (topic_ != nullptr)
    {
        participant_->delete_topic(topic_);
    }
    DomainParticipantFactory::get_instance()->delete_participant(participant_);
}

Continuing with the public member functions of the HelloWorldPublisher class, the next snippet of code defines the public publisher’s initialization member function. This function performs several actions:

  1. Initializes the content of the HelloWorld type hello_ structure members.

  2. Assigns a name to the participant through the QoS of the DomainParticipant.

  3. Uses the DomainParticipantFactory to create the participant.

  4. Registers the data type defined in the IDL.

  5. Creates the topic for the publications.

  6. Creates the publisher.

  7. Creates the DataWriter with the listener previously created.

As you can see, the QoS configuration for all entities, except for the participant’s name, is the default configuration (PARTICIPANT_QOS_DEFAULT, PUBLISHER_QOS_DEFAULT, TOPIC_QOS_DEFAULT, DATAWRITER_QOS_DEFAULT). The default value of the QoS of each DDS Entity can be checked in the DDS standard.

//!Initialize the publisher
bool init()
{
    hello_.index(0);
    hello_.message("HelloWorld");

    DomainParticipantQos participantQos;
    participantQos.name("Participant_publisher");
    participant_ = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);

    if (participant_ == nullptr)
    {
        return false;
    }

    // Register the Type
    type_.register_type(participant_);

    // Create the publications Topic
    topic_ = participant_->create_topic("HelloWorldTopic", "HelloWorld", TOPIC_QOS_DEFAULT);

    if (topic_ == nullptr)
    {
        return false;
    }

    // Create the Publisher
    publisher_ = participant_->create_publisher(PUBLISHER_QOS_DEFAULT, nullptr);

    if (publisher_ == nullptr)
    {
        return false;
    }

    // Create the DataWriter
    writer_ = publisher_->create_datawriter(topic_, DATAWRITER_QOS_DEFAULT, &listener_);

    if (writer_ == nullptr)
    {
        return false;
    }
    return true;
}

To make the publication, the public member function publish() is implemented. In the DataWriter’s listener callback which states that the DataWriter has matched with a DataReader that listens to the publication topic, the data member matched_ is updated. It contains the number of DataReaders discovered. Therefore, when the first DataReader has been discovered, the application starts to publish. This is simply the writing of a change by the DataWriter object.

//!Send a publication
bool publish()
{
    if (listener_.matched_ > 0)
    {
        hello_.index(hello_.index() + 1);
        writer_->write(&hello_);
        return true;
    }
    return false;
}

The public run function executes the action of publishing a given number of times, waiting for 1 second between publications.

//!Run the Publisher
void run(
        uint32_t samples)
{
    uint32_t samples_sent = 0;
    while (samples_sent < samples)
    {
        if (publish())
        {
            samples_sent++;
            std::cout << "Message: " << hello_.message() << " with index: " << hello_.index()
                        << " SENT" << std::endl;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

Finally, the HelloWorldPublisher is initialized and run in main.

int main(
        int argc,
        char** argv)
{
    std::cout << "Starting publisher." << std::endl;
    uint32_t samples = 10;

    HelloWorldPublisher* mypub = new HelloWorldPublisher();
    if(mypub->init())
    {
        mypub->run(samples);
    }

    delete mypub;
    return 0;
}
1.3.7.2. CMakeLists.txt

Include at the end of the CMakeList.txt file you created earlier the following code snippet. This adds all the source files needed to build the executable, and links the executable and the library together.

add_executable(DDSHelloWorldPublisher src/HelloWorldPublisher.cpp ${DDS_HELLOWORLD_SOURCES_CXX})
target_link_libraries(DDSHelloWorldPublisher fastdds fastcdr)

At this point the project is ready for building, compiling and running the publisher application. From the build directory in the workspace, run the following commands.

cmake ..
cmake --build .
./DDSHelloWorldPublisher

1.3.8. Write the Fast DDS subscriber

From the src directory in the workspace, execute the following command to download the HelloWorldSubscriber.cpp file.

wget -O HelloWorldSubscriber.cpp \
    https://raw.githubusercontent.com/eProsima/Fast-RTPS-docs/master/code/Examples/C++/DDSHelloWorld/src/HelloWorldSubscriber.cpp

This is the C++ source code for the subscriber application. The application runs a subscriber until it receives 10 samples under the topic HelloWorldTopic. At this point the subscriber stops.

  1// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
  2//
  3// Licensed under the Apache License, Version 2.0 (the "License");
  4// you may not use this file except in compliance with the License.
  5// You may obtain a copy of the License at
  6//
  7//     http://www.apache.org/licenses/LICENSE-2.0
  8//
  9// Unless required by applicable law or agreed to in writing, software
 10// distributed under the License is distributed on an "AS IS" BASIS,
 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12// See the License for the specific language governing permissions and
 13// limitations under the License.
 14
 15/**
 16 * @file HelloWorldSubscriber.cpp
 17 *
 18 */
 19
 20#include "HelloWorldPubSubTypes.hpp"
 21
 22#include <chrono>
 23#include <thread>
 24
 25#include <fastdds/dds/domain/DomainParticipant.hpp>
 26#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
 27#include <fastdds/dds/subscriber/DataReader.hpp>
 28#include <fastdds/dds/subscriber/DataReaderListener.hpp>
 29#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
 30#include <fastdds/dds/subscriber/SampleInfo.hpp>
 31#include <fastdds/dds/subscriber/Subscriber.hpp>
 32#include <fastdds/dds/topic/TypeSupport.hpp>
 33
 34using namespace eprosima::fastdds::dds;
 35
 36class HelloWorldSubscriber
 37{
 38private:
 39
 40    DomainParticipant* participant_;
 41
 42    Subscriber* subscriber_;
 43
 44    DataReader* reader_;
 45
 46    Topic* topic_;
 47
 48    TypeSupport type_;
 49
 50    class SubListener : public DataReaderListener
 51    {
 52    public:
 53
 54        SubListener()
 55            : samples_(0)
 56        {
 57        }
 58
 59        ~SubListener() override
 60        {
 61        }
 62
 63        void on_subscription_matched(
 64                DataReader*,
 65                const SubscriptionMatchedStatus& info) override
 66        {
 67            if (info.current_count_change == 1)
 68            {
 69                std::cout << "Subscriber matched." << std::endl;
 70            }
 71            else if (info.current_count_change == -1)
 72            {
 73                std::cout << "Subscriber unmatched." << std::endl;
 74            }
 75            else
 76            {
 77                std::cout << info.current_count_change
 78                          << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl;
 79            }
 80        }
 81
 82        void on_data_available(
 83                DataReader* reader) override
 84        {
 85            SampleInfo info;
 86            if (reader->take_next_sample(&hello_, &info) == eprosima::fastdds::dds::RETCODE_OK)
 87            {
 88                if (info.valid_data)
 89                {
 90                    samples_++;
 91                    std::cout << "Message: " << hello_.message() << " with index: " << hello_.index()
 92                              << " RECEIVED." << std::endl;
 93                }
 94            }
 95        }
 96
 97        HelloWorld hello_;
 98
 99        std::atomic_int samples_;
100
101    }
102    listener_;
103
104public:
105
106    HelloWorldSubscriber()
107        : participant_(nullptr)
108        , subscriber_(nullptr)
109        , topic_(nullptr)
110        , reader_(nullptr)
111        , type_(new HelloWorldPubSubType())
112    {
113    }
114
115    virtual ~HelloWorldSubscriber()
116    {
117        if (reader_ != nullptr)
118        {
119            subscriber_->delete_datareader(reader_);
120        }
121        if (topic_ != nullptr)
122        {
123            participant_->delete_topic(topic_);
124        }
125        if (subscriber_ != nullptr)
126        {
127            participant_->delete_subscriber(subscriber_);
128        }
129        DomainParticipantFactory::get_instance()->delete_participant(participant_);
130    }
131
132    //!Initialize the subscriber
133    bool init()
134    {
135        DomainParticipantQos participantQos;
136        participantQos.name("Participant_subscriber");
137        participant_ = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);
138
139        if (participant_ == nullptr)
140        {
141            return false;
142        }
143
144        // Register the Type
145        type_.register_type(participant_);
146
147        // Create the subscriptions Topic
148        topic_ = participant_->create_topic("HelloWorldTopic", "HelloWorld", TOPIC_QOS_DEFAULT);
149
150        if (topic_ == nullptr)
151        {
152            return false;
153        }
154
155        // Create the Subscriber
156        subscriber_ = participant_->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr);
157
158        if (subscriber_ == nullptr)
159        {
160            return false;
161        }
162
163        // Create the DataReader
164        reader_ = subscriber_->create_datareader(topic_, DATAREADER_QOS_DEFAULT, &listener_);
165
166        if (reader_ == nullptr)
167        {
168            return false;
169        }
170
171        return true;
172    }
173
174    //!Run the Subscriber
175    void run(
176            uint32_t samples)
177    {
178        while (listener_.samples_ < samples)
179        {
180            std::this_thread::sleep_for(std::chrono::milliseconds(100));
181        }
182    }
183
184};
185
186int main(
187        int argc,
188        char** argv)
189{
190    std::cout << "Starting subscriber." << std::endl;
191    uint32_t samples = 10;
192
193    HelloWorldSubscriber* mysub = new HelloWorldSubscriber();
194    if (mysub->init())
195    {
196        mysub->run(samples);
197    }
198
199    delete mysub;
200    return 0;
201}
1.3.8.1. Examining the code

Since the source code of both the publisher and subscriber applications is mostly identical, this document will focus on the main differences between them, omitting the parts of the code that have already been explained.

Following the same structure as in the publisher explanation, the first step is the includes of the C++ header files. In these, the files that include the publisher class are replaced by the subscriber class and the data writer class by the data reader class.

  • Subscriber. It is the object responsible for the creation and configuration of DataReaders.

  • DataReader. It is the object responsible for the actual reception of the data. It registers in the application the topic (TopicDescription) that identifies the data to be read and accesses the data received by the subscriber.

  • DataReaderListener. This is the listener assigned to the data reader.

  • DataReaderQoS. Structure that defines the QoS of the DataReader.

  • SampleInfo. It is the information that accompanies each sample that is ‘read’ or ‘taken’.

#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>

The next line defines the HelloWorldSubscriber class that implements a subscriber.

class HelloWorldSubscriber

Starting with the private data members of the class, it is worth mentioning the implementation of the data reader listener. The private data members of the class will be the participant, the subscriber, the topic, the data reader, and the data type. As it was the case with the data writer, the listener implements the callbacks to be executed in case an event occurs. The first overridden callback of the SubListener is the on_subscription_matched(), which is the analog of the on_publication_matched() callback of the DataWriter.

void on_subscription_matched(
        DataReader*,
        const SubscriptionMatchedStatus& info) override
{
    if (info.current_count_change == 1)
    {
        std::cout << "Subscriber matched." << std::endl;
    }
    else if (info.current_count_change == -1)
    {
        std::cout << "Subscriber unmatched." << std::endl;
    }
    else
    {
        std::cout << info.current_count_change
                  << " is not a valid value for SubscriptionMatchedStatus current count change" << std::endl;
    }
}

The second overridden callback is on_data_available(). In this, the next received sample that the data reader can access is taken and processed to display its content. It is here that the object of the SampleInfo class is defined, which determines whether a sample has already been read or taken. Each time a sample is read, the counter of samples received is increased.

void on_data_available(
        DataReader* reader) override
{
    SampleInfo info;
    if (reader->take_next_sample(&hello_, &info) == eprosima::fastdds::dds::RETCODE_OK)
    {
        if (info.valid_data)
        {
            samples_++;
            std::cout << "Message: " << hello_.message() << " with index: " << hello_.index()
                      << " RECEIVED." << std::endl;
        }
    }
}

The public constructor and destructor of the class is defined below.

HelloWorldSubscriber()
    : participant_(nullptr)
    , subscriber_(nullptr)
    , topic_(nullptr)
    , reader_(nullptr)
    , type_(new HelloWorldPubSubType())
{
}

virtual ~HelloWorldSubscriber()
{
    if (reader_ != nullptr)
    {
        subscriber_->delete_datareader(reader_);
    }
    if (topic_ != nullptr)
    {
        participant_->delete_topic(topic_);
    }
    if (subscriber_ != nullptr)
    {
        participant_->delete_subscriber(subscriber_);
    }
    DomainParticipantFactory::get_instance()->delete_participant(participant_);

Next comes the subscriber initialization public member function. This is the same as the initialization public member function defined for the HelloWorldPublisher. The QoS configuration for all entities, except for the participant’s name, is the default QoS (PARTICIPANT_QOS_DEFAULT, SUBSCRIBER_QOS_DEFAULT, TOPIC_QOS_DEFAULT, DATAREADER_QOS_DEFAULT). The default value of the QoS of each DDS Entity can be checked in the DDS standard.

//!Initialize the subscriber
bool init()
{
    DomainParticipantQos participantQos;
    participantQos.name("Participant_subscriber");
    participant_ = DomainParticipantFactory::get_instance()->create_participant(0, participantQos);

    if (participant_ == nullptr)
    {
        return false;
    }

    // Register the Type
    type_.register_type(participant_);

    // Create the subscriptions Topic
    topic_ = participant_->create_topic("HelloWorldTopic", "HelloWorld", TOPIC_QOS_DEFAULT);

    if (topic_ == nullptr)
    {
        return false;
    }

    // Create the Subscriber
    subscriber_ = participant_->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr);

    if (subscriber_ == nullptr)
    {
        return false;
    }

    // Create the DataReader
    reader_ = subscriber_->create_datareader(topic_, DATAREADER_QOS_DEFAULT, &listener_);

    if (reader_ == nullptr)
    {
        return false;
    }

    return true;

The public member function run() ensures that the subscriber runs until all the samples have been received. This member function implements an active wait of the subscriber, with a 100ms sleep interval to ease the CPU.

//!Run the Subscriber
void run(
        uint32_t samples)
{
    while (listener_.samples_ < samples)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

Finally, the participant that implements a subscriber is initialized and run in main.

};

int main(
        int argc,
        char** argv)
{
    std::cout << "Starting subscriber." << std::endl;
    uint32_t samples = 10;

    HelloWorldSubscriber* mysub = new HelloWorldSubscriber();
    if (mysub->init())
    {
        mysub->run(samples);
    }

    delete mysub;
1.3.8.2. CMakeLists.txt

Include at the end of the CMakeList.txt file you created earlier the following code snippet. This adds all the source files needed to build the executable, and links the executable and the library together.

add_executable(DDSHelloWorldSubscriber src/HelloWorldSubscriber.cpp ${DDS_HELLOWORLD_SOURCES_CXX})
target_link_libraries(DDSHelloWorldSubscriber fastdds fastcdr)

At this point the project is ready for building, compiling and running the subscriber application. From the build directory in the workspace, run the following commands.

cmake ..
cmake --build .
./DDSHelloWorldSubscriber

1.3.9. Putting all together

Finally, from the build directory, run the publisher and subscriber applications from two terminals.

./DDSHelloWorldPublisher
./DDSHelloWorldSubscriber

1.3.10. Summary

In this tutorial you have built a publisher and a subscriber DDS application. You have also learned how to build the CMake file for source code compilation, and how to include and use the Fast DDS and Fast CDR libraries in your project.

1.3.11. Next steps

In the eProsima Fast DDS Github repository you will find more complex examples that implement DDS communication for a multitude of use cases and scenarios. You can find them here.

1.4. Writing a simple Python publisher and subscriber application

This section details how to create a simple Fast DDS application with a publisher and a subscriber using Python API step by step.

1.4.1. Background

DDS is a data-centric communications middleware that implements the DCPS model. This model is based on the development of a publisher, a data generating element; and a subscriber, a data consuming element. These entities communicate by means of the topic, an element that binds both DDS entities. Publishers generate information under a topic and subscribers subscribe to this same topic to receive information.

1.4.2. Prerequisites

First of all, please follow the steps outlined in the Installation Manual section for the installation of eProsima Fast DDS Python and all its dependencies.

Note

All the commands provided in this tutorial are outlined for a Linux environment.

1.4.3. Create the application workspace

The application workspace will have the following structure at the end of the project. Files HelloWorldPublisher.py and HelloWorldSubscriber.py are the Publisher application and Subscriber application respectively.

.
├── CMakeCache.txt
├── CMakeFiles
├── CMakeLists.txt
├── HelloWorld.hpp
├── HelloWorld.i
├── HelloWorld.idl
├── HelloWorld.py
├── HelloWorldCdrAux.hpp
├── HelloWorldCdrAux.ipp
├── HelloWorldPubSubTypes.cxx
├── HelloWorldPubSubTypes.h
├── HelloWorldPubSubTypes.i
├── HelloWorldPublisher.py
├── HelloWorldSubscriber.py
├── HelloWorldTypeObjectSupport.cxx
├── HelloWorldTypeObjectSupport.hpp
├── Makefile
├── _HelloWorldWrapper.so
├── cmake_install.cmake
└── libHelloWorld.so

Let’s create the directory tree first.

mkdir workspace_HelloWorld && cd workspace_HelloWorld

1.4.4. Import linked libraries and its dependencies

The DDS application requires the Fast DDS, Fast CDR and Fast DDS Python bindings libraries. Depending on the installation procedure followed the process of making these libraries available for our DDS application will be slightly different.

1.4.4.1. Colcon installation

From a Colcon installation there are several ways to import the libraries. If the libraries need to be available just for the current session, run the following command.

source <path/to/Fast-DDS-python/workspace>/install/setup.bash

They can be made accessible from any session by adding the Fast DDS installation directory to your $PATH variable in the shell configuration files for the current user running the following command.

echo 'source <path/to/Fast-DDS-python/workspace>/install/setup.bash' >> ~/.bashrc

This will set up the environment after each of this user’s logins.

1.4.5. Build the topic data type

eProsima Fast DDS-Gen is a Java application that generates source code using the data types defined in an Interface Description Language (IDL) file. This application can do two different things:

  1. Generate C++ definitions for your custom topic.

  2. Generate SWIG interface files to generate the Python bindings for your custom topic.

For this project, we will use the Fast DDS-Gen application to define the data type of the messages that will be sent by the publishers and received by the subscribers.

In the workspace directory, execute the following commands:

touch HelloWorld.idl

This creates the HelloWorld.idl file. Open the file in a text editor and copy and paste the following snippet of code.

struct HelloWorld
{
    unsigned long index;
    string message;
};

By doing this we have defined the HelloWorld data type, which has two elements: an index of type uint32_t and a message of type std::string. All that remains is to generate the source code that implements this data type in C++11 and the SWIG interface files for the Python bindings. To do this, run the following command.

<path/to/Fast DDS-Gen>/scripts/fastddsgen -python HelloWorld.idl

This must have generated the following files:

  • HelloWorld.hpp: HelloWorld C++ type definition.

  • HelloWorld.i: SWIG interface file for HelloWorld C++ type definition.

  • HelloWorldPubSubTypes.cxx: C++ interface used by Fast DDS to support HelloWorld type.

  • HelloWorldPubSubTypes.h: C++ header file for HelloWorldPubSubTypes.cxx.

  • HelloWorldPubSubTypes.i: SWIG interface file for C++ Serialization and Deserialization code.

  • HelloWorldCdrAux.ipp: C++ serialization and deserialization code for the HelloWorld type.

  • HelloWorldCdrAux.hpp: C++ header file for HelloWorldCdrAux.ipp.

  • HelloWorldTypeObjectSupport.cxx: TypeObject representation registration code.

  • HelloWorldTypeObjectSupport.hpp: Header file for HelloWorldTypeObjectSupport.cxx.

  • CMakeLists.txt: CMake file to generate C++ source code and Python module from the SWIG interface files, compile and generate C++ libraries.

After that, the python bindings can be generated by running the following command.

cmake .
make

This must have generated the python binding:

  • HelloWorld.py: Python module to be imported by your Python example.

1.4.5.1. CMakeLists.txt

At this point the project is ready for building, compiling and generating Python bindings for this data type. From the workspace, run the following commands.

cmake .
make

1.4.6. Write the Fast DDS publisher

From the workspace, run the following command to download the HelloWorldPublisher.py file.

wget -O HelloWorldPublisher.py \
    https://raw.githubusercontent.com/eProsima/Fast-RTPS-docs/master/code/Examples/Python/HelloWorld/HelloWorldPublisher.py

This is the Python source code for the publisher application. It is going to send 10 publications under the topic HelloWorldTopic.

  1# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
  2#
  3# Licensed under the Apache License, Version 2.0 (the "License");
  4# you may not use this file except in compliance with the License.
  5# You may obtain a copy of the License at
  6#
  7#     http://www.apache.org/licenses/LICENSE-2.0
  8#
  9# Unless required by applicable law or agreed to in writing, software
 10# distributed under the License is distributed on an "AS IS" BASIS,
 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12# See the License for the specific language governing permissions and
 13# limitations under the License.
 14"""
 15HelloWorld Publisher
 16"""
 17from threading import Condition
 18import time
 19
 20import fastdds
 21import HelloWorld
 22
 23DESCRIPTION = """HelloWorld Publisher example for Fast DDS python bindings"""
 24USAGE = ('python3 HelloWorldPublisher.py')
 25
 26class WriterListener (fastdds.DataWriterListener) :
 27    def __init__(self, writer) :
 28        self._writer = writer
 29        super().__init__()
 30
 31
 32    def on_publication_matched(self, datawriter, info) :
 33        if (0 < info.current_count_change) :
 34            print ("Publisher matched subscriber {}".format(info.last_subscription_handle))
 35            self._writer._cvDiscovery.acquire()
 36            self._writer._matched_reader += 1
 37            self._writer._cvDiscovery.notify()
 38            self._writer._cvDiscovery.release()
 39        else :
 40            print ("Publisher unmatched subscriber {}".format(info.last_subscription_handle))
 41            self._writer._cvDiscovery.acquire()
 42            self._writer._matched_reader -= 1
 43            self._writer._cvDiscovery.notify()
 44            self._writer._cvDiscovery.release()
 45
 46
 47class Writer:
 48
 49
 50    def __init__(self):
 51        self._matched_reader = 0
 52        self._cvDiscovery = Condition()
 53        self.index = 0
 54
 55        factory = fastdds.DomainParticipantFactory.get_instance()
 56        self.participant_qos = fastdds.DomainParticipantQos()
 57        factory.get_default_participant_qos(self.participant_qos)
 58        self.participant = factory.create_participant(0, self.participant_qos)
 59
 60        self.topic_data_type = HelloWorld.HelloWorldPubSubType()
 61        self.topic_data_type.set_name("HelloWorld")
 62        self.type_support = fastdds.TypeSupport(self.topic_data_type)
 63        self.participant.register_type(self.type_support)
 64
 65        self.topic_qos = fastdds.TopicQos()
 66        self.participant.get_default_topic_qos(self.topic_qos)
 67        self.topic = self.participant.create_topic("HelloWorldTopic", self.topic_data_type.get_name(), self.topic_qos)
 68
 69        self.publisher_qos = fastdds.PublisherQos()
 70        self.participant.get_default_publisher_qos(self.publisher_qos)
 71        self.publisher = self.participant.create_publisher(self.publisher_qos)
 72
 73        self.listener = WriterListener(self)
 74        self.writer_qos = fastdds.DataWriterQos()
 75        self.publisher.get_default_datawriter_qos(self.writer_qos)
 76        self.writer = self.publisher.create_datawriter(self.topic, self.writer_qos, self.listener)
 77
 78
 79    def write(self):
 80        data = HelloWorld.HelloWorld()
 81        data.message("Hello World")
 82        data.index(self.index)
 83        self.writer.write(data)
 84        print("Sending {message} : {index}".format(message=data.message(), index=data.index()))
 85        self.index = self.index + 1
 86
 87
 88    def wait_discovery(self) :
 89        self._cvDiscovery.acquire()
 90        print ("Writer is waiting discovery...")
 91        self._cvDiscovery.wait_for(lambda : self._matched_reader != 0)
 92        self._cvDiscovery.release()
 93        print("Writer discovery finished...")
 94
 95
 96    def run(self):
 97        self.wait_discovery()
 98        for x in range(10) :
 99            time.sleep(1)
100            self.write()
101        self.delete()
102
103
104    def delete(self):
105        factory = fastdds.DomainParticipantFactory.get_instance()
106        self.participant.delete_contained_entities()
107        factory.delete_participant(self.participant)
108
109
110if __name__ == '__main__':
111    print('Starting publisher.')
112    writer = Writer()
113    writer.run()
114    exit()
1.4.6.1. Examining the code

At the beginning of the file we import the Fast DDS Python bindings.

import fastdds

and also the Python module generated by Fast-DDS-Gen as described in Build the topic data type section.

import HelloWorld

Then, the WriterListener class is defined by inheriting from the DataWriterListener class. This class overrides the default DataWriter listener callbacks, which allows the execution of routines in case of an event. The overridden callback on_publication_matched() allows the definition of a series of actions when a new DataReader is detected listening to the topic under which the DataWriter is publishing. The info.current_count_change() detects these changes of DataReaders that are matched to the DataWriter. This is a member in the MatchedStatus structure that allows tracking changes in the status of subscriptions.

class WriterListener (fastdds.DataWriterListener) :
    def __init__(self, writer) :
        self._writer = writer
        super().__init__()


    def on_publication_matched(self, datawriter, info) :
        if (0 < info.current_count_change) :
            print ("Publisher matched subscriber {}".format(info.last_subscription_handle))
            self._writer._cvDiscovery.acquire()
            self._writer._matched_reader += 1
            self._writer._cvDiscovery.notify()
            self._writer._cvDiscovery.release()
        else :
            print ("Publisher unmatched subscriber {}".format(info.last_subscription_handle))
            self._writer._cvDiscovery.acquire()
            self._writer._matched_reader -= 1
            self._writer._cvDiscovery.notify()
            self._writer._cvDiscovery.release()

The next block creates the Writer class that implements a publisher.

class Writer:

The publisher’s initialization member function of the Writer class are defined below. This function performs several actions:

  1. Uses the DomainParticipantFactory to create the participant.

  2. Registers the data type defined in the IDL.

  3. Creates the topic for the publications.

  4. Creates the publisher.

  5. Creates the DataWriter with the listener previously created.

def __init__(self):
    self._matched_reader = 0
    self._cvDiscovery = Condition()
    self.index = 0

    factory = fastdds.DomainParticipantFactory.get_instance()
    self.participant_qos = fastdds.DomainParticipantQos()
    factory.get_default_participant_qos(self.participant_qos)
    self.participant = factory.create_participant(0, self.participant_qos)

    self.topic_data_type = HelloWorld.HelloWorldPubSubType()
    self.topic_data_type.set_name("HelloWorld")
    self.type_support = fastdds.TypeSupport(self.topic_data_type)
    self.participant.register_type(self.type_support)

    self.topic_qos = fastdds.TopicQos()
    self.participant.get_default_topic_qos(self.topic_qos)
    self.topic = self.participant.create_topic("HelloWorldTopic", self.topic_data_type.get_name(), self.topic_qos)

    self.publisher_qos = fastdds.PublisherQos()
    self.participant.get_default_publisher_qos(self.publisher_qos)
    self.publisher = self.participant.create_publisher(self.publisher_qos)

    self.listener = WriterListener(self)
    self.writer_qos = fastdds.DataWriterQos()
    self.publisher.get_default_datawriter_qos(self.writer_qos)
    self.writer = self.publisher.create_datawriter(self.topic, self.writer_qos, self.listener)

To make the publication, the public member function write() is implemented. This is simply the writing of a change by the DataWriter object.

    def write(self):
        data = HelloWorld.HelloWorld()
        data.message("Hello World")
        data.index(self.index)
        self.writer.write(data)
        print("Sending {message} : {index}".format(message=data.message(), index=data.index()))
        self.index = self.index + 1

To detect when a DataReader has matched, the public member function wait_discovery() is implemented. In the DataWriter’s listener callback which states that the DataWriter has matched with a DataReader that listens to the publication topic, the data member _matched_reader is updated. It contains the number of DataReaders discovered. Therefore, when the first DataReader has been discovered, the application starts to publish.

def wait_discovery(self) :
    self._cvDiscovery.acquire()
    print ("Writer is waiting discovery...")
    self._cvDiscovery.wait_for(lambda : self._matched_reader != 0)
    self._cvDiscovery.release()
    print("Writer discovery finished...")

The public run function waits until a DataReader is discovered and executes the action of publishing 10 samples.

def run(self):
    self.wait_discovery()
    for x in range(10) :
        time.sleep(1)
        self.write()
    self.delete()

Finally, the Writer is initialized and run in main.

if __name__ == '__main__':
    print('Starting publisher.')
    writer = Writer()
    writer.run()
    exit()

1.4.7. Write the Fast DDS subscriber

From the workspace, run the following command to download the HelloWorldSubscriber.py file.

wget -O HelloWorldSubscriber.py \
    https://raw.githubusercontent.com/eProsima/Fast-RTPS-docs/master/code/Examples/Python/HelloWorld/HelloWorldSubscriber.py

This is the Python source code for the subscriber application. The application runs a subscriber until the user press Ctrl+C receiving samples under the topic HelloWorldTopic.

 1# Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
 2#
 3# Licensed under the Apache License, Version 2.0 (the "License");
 4# you may not use this file except in compliance with the License.
 5# You may obtain a copy of the License at
 6#
 7#     http://www.apache.org/licenses/LICENSE-2.0
 8#
 9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""
15HelloWorld Subscriber
16"""
17import signal
18
19import fastdds
20import HelloWorld
21
22DESCRIPTION = """HelloWorld Subscriber example for Fast DDS python bindings"""
23USAGE = ('python3 HelloWorldSubscriber.py')
24
25# To capture ctrl+C
26def signal_handler(sig, frame):
27    print('Interrupted!')
28
29class ReaderListener(fastdds.DataReaderListener):
30
31
32    def __init__(self):
33        super().__init__()
34
35
36    def on_subscription_matched(self, datareader, info) :
37        if (0 < info.current_count_change) :
38            print ("Subscriber matched publisher {}".format(info.last_publication_handle))
39        else :
40            print ("Subscriber unmatched publisher {}".format(info.last_publication_handle))
41
42
43    def on_data_available(self, reader):
44        info = fastdds.SampleInfo()
45        data = HelloWorld.HelloWorld()
46        reader.take_next_sample(data, info)
47
48        print("Received {message} : {index}".format(message=data.message(), index=data.index()))
49
50
51class Reader:
52
53
54    def __init__(self):
55        factory = fastdds.DomainParticipantFactory.get_instance()
56        self.participant_qos = fastdds.DomainParticipantQos()
57        factory.get_default_participant_qos(self.participant_qos)
58        self.participant = factory.create_participant(0, self.participant_qos)
59
60        self.topic_data_type = HelloWorld.HelloWorldPubSubType()
61        self.topic_data_type.set_name("HelloWorld")
62        self.type_support = fastdds.TypeSupport(self.topic_data_type)
63        self.participant.register_type(self.type_support)
64
65        self.topic_qos = fastdds.TopicQos()
66        self.participant.get_default_topic_qos(self.topic_qos)
67        self.topic = self.participant.create_topic("HelloWorldTopic", self.topic_data_type.get_name(), self.topic_qos)
68
69        self.subscriber_qos = fastdds.SubscriberQos()
70        self.participant.get_default_subscriber_qos(self.subscriber_qos)
71        self.subscriber = self.participant.create_subscriber(self.subscriber_qos)
72
73        self.listener = ReaderListener()
74        self.reader_qos = fastdds.DataReaderQos()
75        self.subscriber.get_default_datareader_qos(self.reader_qos)
76        self.reader = self.subscriber.create_datareader(self.topic, self.reader_qos, self.listener)
77
78
79    def delete(self):
80        factory = fastdds.DomainParticipantFactory.get_instance()
81        self.participant.delete_contained_entities()
82        factory.delete_participant(self.participant)
83
84
85    def run(self):
86        signal.signal(signal.SIGINT, signal_handler)
87        print('Press Ctrl+C to stop')
88        signal.pause()
89        self.delete()
90
91
92if __name__ == '__main__':
93    print('Creating subscriber.')
94    reader = Reader()
95    reader.run()
96    exit()
1.4.7.1. Examining the code

Since the source code of both the publisher and subscriber applications is mostly identical, this document will focus on the main differences between them, omitting the parts of the code that have already been explained.

Following the same structure as in the publisher explanation, the first step is the implementation of the data reader listener. The first overridden callback of the ReaderListener is the on_subscription_matched(), which is the analog of the on_publication_matched() callback of the DataWriter.

def on_subscription_matched(self, datareader, info) :
    if (0 < info.current_count_change) :
        print ("Subscriber matched publisher {}".format(info.last_publication_handle))
    else :
        print ("Subscriber unmatched publisher {}".format(info.last_publication_handle))

The second overridden callback is on_data_available(). In this, the next received sample that the data reader can access is taken and processed to display its content. It is here that the object of the SampleInfo class is defined, which determines whether a sample has already been read or taken.

def on_data_available(self, reader):
    info = fastdds.SampleInfo()
    data = HelloWorld.HelloWorld()
    reader.take_next_sample(data, info)

The next line defines the Reader class that implements a subscriber.

class Reader:

Next comes the subscriber initialization public member function. This is the same as the initialization public member function defined for the Writer.

def __init__(self):
    factory = fastdds.DomainParticipantFactory.get_instance()
    self.participant_qos = fastdds.DomainParticipantQos()
    factory.get_default_participant_qos(self.participant_qos)
    self.participant = factory.create_participant(0, self.participant_qos)

    self.topic_data_type = HelloWorld.HelloWorldPubSubType()
    self.topic_data_type.set_name("HelloWorld")
    self.type_support = fastdds.TypeSupport(self.topic_data_type)
    self.participant.register_type(self.type_support)

    self.topic_qos = fastdds.TopicQos()
    self.participant.get_default_topic_qos(self.topic_qos)
    self.topic = self.participant.create_topic("HelloWorldTopic", self.topic_data_type.get_name(), self.topic_qos)

    self.subscriber_qos = fastdds.SubscriberQos()
    self.participant.get_default_subscriber_qos(self.subscriber_qos)
    self.subscriber = self.participant.create_subscriber(self.subscriber_qos)

    self.listener = ReaderListener()
    self.reader_qos = fastdds.DataReaderQos()
    self.subscriber.get_default_datareader_qos(self.reader_qos)
    self.reader = self.subscriber.create_datareader(self.topic, self.reader_qos, self.listener)

The public member function run() ensures that the subscriber runs until the user press Ctrl+C.

def run(self):
    signal.signal(signal.SIGINT, signal_handler)
    print('Press Ctrl+C to stop')
    signal.pause()
    self.delete()

Finally, the participant that implements a subscriber is initialized and run in main.

if __name__ == '__main__':
    print('Creating subscriber.')
    reader = Reader()
    reader.run()
    exit()

1.4.8. Putting all together

Finally, from the build directory, run the publisher and subscriber applications from two terminals.

python3 HelloWorldPublisher.py
python3 HelloWorldSubscriber.py

1.4.9. Summary

In this tutorial you have built a Python publisher and a subscriber DDS application. You have also learned how to generate from an IDL file the specific Python module for your Topic data type.

1.4.10. Next steps

In the eProsima Fast DDS Github repository you will find more complex examples that implement DDS communication for a multitude of use cases and scenarios. You can find them here.

See also

Check Fast DDS dependencies, libraries, and related packages in the Dependencies and compatibilities section.

2. Library Overview

Fast DDS (formerly Fast RTPS) is an efficient and high-performance implementation of the DDS specification, a data-centric communications middleware (DCPS) for distributed application software. This section reviews the architecture, operation and key features of Fast DDS.

2.1. Architecture

The architecture of Fast DDS is shown in the figure below, where a layer model with the following different environments can be seen.

  • Application layer. The user application that makes use of the Fast DDS API for the implementation of communications in distributed systems.

  • Fast DDS layer. Robust implementation of the DDS communications middleware. It allows the deployment of one or more DDS domains in which DomainParticipants within the same domain exchange messages by publishing/subscribing under a domain topic.

  • RTPS layer. Implementation of the Real-Time Publish-Subscribe (RTPS) protocol for interoperability with DDS applications. This layer acts as an abstraction layer of the transport layer.

  • Transport Layer. Fast DDS can be used over various transport protocols such as unreliable transport protocols (UDP), reliable transport protocols (TCP), or shared memory transport protocols (SHM).

_images/library_overview.svg

Fast DDS layer model architecture

2.1.1. DDS Layer

Several key elements for communication are defined in the DDS layer of Fast DDS. The user will create these elements in their application, thus incorporating DDS application elements and creating a data-centric communication system. Fast DDS, following the DDS specification, defines these elements involved in communication as Entities. A DDS Entity is any object that supports Quality of Service configuration (QoS), and that implements a listener.

  • QoS. The mechanism by which the behavior of each of the entities is defined.

  • Listener. The mechanism by which the entities are notified of the possible events that arise during the application’s execution.

Below are listed the DDS Entities together with their description and functionality. For a more detailed explanation of each entity, their QoS, and their listeners, please refer to DDS Layer section.

  • Domain. A positive integer which identifies the DDS domain. Each DomainParticipant will have an assigned DDS domain, so that DomainParticipants in the same domain can communicate, as well as isolate communications between DDS domains. This value must be given by the application developer when creating the DomainParticipants.

  • DomainParticipant. Object containing other DDS entities such as publishers, subscribers, topics and multitopics. It is the entity that allows the creation of the previous entities it contains, as well as the configuration of their behavior.

  • Publisher. The Publisher publishes data under a topic using a DataWriter, which writes the data to the transport. It is the entity that creates and configures the DataWriter entities it contains, and may contain one or more of them.

  • DataWriter. It is the entity in charge of publishing messages. The user must provide a Topic when creating this entity which will be the Topic under which the data will be published. Publication is done by writing the data-objects as a change in the DataWriterHistory.

  • DataWriterHistory. This is a list of changes to the data-objects. When the DataWriter proceeds to publish data under a specific Topic, it actually creates a change in this data. It is this change that is registered in the History. These changes are then sent to the DataReader that subscribes to that specific topic.

  • Subscriber. The Subscriber subscribes to a topic using a DataReader, which reads the data from the transport. It is the entity that creates and configures the DataReader entities it contains, and may contain one or more DataReader entities.

  • DataReader. It is the entity that subscribes to the topics for the reception of publications. The user must provide a subscription Topic when creating this entity. A DataReader receives the messages as changes in its DataReaderHistory.

  • DataReaderHistory. It contains the changes in the data-objects that the DataReader receives as a result of subscribing to a certain Topic.

  • Topic. Entity that binds Publishers’ DataWriters with Subscribers’ DataReaders.

2.1.2. RTPS layer

As mentioned above, the RTPS protocol in Fast DDS allows the abstraction of DDS application entities from the transport layer. According to the graph shown above, the RTPS layer has four main Entities.

  • RTPSDomain. It is the extension of the DDS domain to the RTPS protocol.

  • RTPSParticipant. Entity containing other RTPS entities. It allows the configuration and creation of the entities it contains.

  • RTPSWriter. The source of the messages. It reads the changes written in the DataWriterHistory and transmits them to all the RTPSReaders to which it has previously matched.

  • RTPSReader. Receiving entity of the messages. It writes the changes reported by the RTPSWriter into the DataReaderHistory.

For a more detailed explanation of each entity, their attributes, and their listeners, please refer to RTPS Layer section.

2.1.3. Transport layer

Fast DDS supports the implementation of applications over various transport protocols. Those are UDPv4, UDPv6, TCPv4, TCPv6 and Shared Memory Transport (SHM). By default, a DomainParticipant implements a UDPv4 and a SHM transport protocol. The configuration of all supported transport protocols is detailed in the Transport Layer section.

2.2. Programming and execution model

Fast DDS is concurrent and event-based. The following explains the multithreading model that governs the operation of Fast DDS as well as the possible events.

2.2.1. Concurrency and multithreading

Fast DDS implements a concurrent multithreading system. Each DomainParticipant spawns a set of threads to take care of background tasks such as logging, message reception, and asynchronous communication. This should not impact the way you use the library, i.e. the Fast DDS API is thread safe, so you can fearlessly call any methods on the same DomainParticipant from different threads. However, this multithreading implementation must be taken into account when external functions access to resources that are modified by threads running internally in the library. An example of this is the modified resources in the entity listener callbacks.

The complete set of threads spawned by Fast DDS is shown below. Transport related threads (marked as UDP, TCP and SHM types) are only created when the appropriate Transport is used.

Name

Type

Cardinality

OS thread name

Description

Event

General

One per DomainParticipant

dds.ev.<participant_id>

Processes periodic and triggered time events.
See DomainParticipantQos.

Discovery Server Event

General

One per DomainParticipant

dds.ds_ev.<participant_id>

Synchronizes access to the Discovery Server
Database.
See DomainParticipantQos.

Asynchronous Writer

General

One per enabled asynchronous
flow controller. Minimum 1.

dds.asyn.<participant_id>.
<async_flow_controller_index>

Manages asynchronous writes. Even for synchronous writers, some forms of
communication must be initiated in the
background.
See DomainParticipantQos and FlowControllersQos.

Datasharing Listener

General

One per
DataReader

dds.dsha.<reader_id>

Listener thread that processes messages
received via Datasharing.
See DataReaderQos.

Reception

UDP

One per port

dds.udp.<port>

Listener thread that processes incoming
UDP messages.
See TransportConfigQos and UDPTransportDescriptor.

Reception

TCP

One per TCP connection

dds.tcp.<port>

Listener thread that processes incoming
TCP messages.
See TCPTransportDescriptor.

Accept

TCP

One per TCP transport

dds.tcp_accept

Thread that processes incoming TCP connection requests.
See TCPTransportDescriptor.

Keep Alive

TCP

One per TCP transport

dds.tcp_keep

Keep alive thread for TCP connections.
See TCPTransportDescriptor.

Reception

SHM

One per port

dds.shm.<port>

Listener thread that processes incoming
messages via SHM segments.
See TransportConfigQos and SharedMemTransportDescriptor.

Logging

SHM

One per port

dds.shmd.<port>

Stores and dumps transferred packets to a file.
See TransportConfigQos and SharedMemTransportDescriptor.

Watchdog

SHM

One

dds.shm.wdog

Monitors health of open shared memory
segments.
See TransportConfigQos and SharedMemTransportDescriptor.

General Logging

Log

One

dds.log

Accumulates and writes to the appropriate
consumer log entries.
See Logging Thread.

Security Logging

Log

One per
DomainParticipant

dds.slog.<participant_id>

Accumulates and writes security log entries.
See DomainParticipantQos.

Watchdog

Filewatch

One

dds.fwatch

Tracks the status of the watched file for
modifications.
See DomainParticipantFactoryQos.

Callback

Filewatch

One

dds.fwatch.cb

Runs the registered callback when the
watched file changes.
See DomainParticipantFactoryQos.

Reception

TypeLookup Service

Two per DomainParticipant

dds.tls.replies.<participant_id>
dds.tls.requests.<participant_id>

Runs when remote endpoint discovery information has been received
with unknown data type.

Some of these threads are only spawned when certain conditions are met:

  • Datasharing listener thread is created only when Datasharing is in use.

  • Discovery Server Event thread is only created when the DomainParticipant is configured as a Discovery Server SERVER.

  • TCP keep alive thread requires the keep alive period to be configured to a value greater than zero.

  • Security logging and Shared Memory packet logging threads both require certain configuration options to be enabled.

  • Filewatch threads are only spawned if the FASTDDS_ENVIRONMENT_FILE is in use.

Regarding transport threads, Fast DDS by default uses both a UDP and a Shared Memory transport. Port configuration can be configured to suit the specific needs of the deployment, but the default configuration is to always use a metatraffic port and a unicast user traffic port. This applies both to UDP and Shared Memory since TCP does not support multicast. More information can be found at the Default Listening Locators page.

Fast DDS offers the possibility of configuring certain attributes of the threads it creates by means of the ThreadSettings.

2.2.2. Event-driven architecture

There is a time-event system that enables Fast DDS to respond to certain conditions, as well as schedule periodic operations. Few of them are visible to the user since most are related to DDS and RTPS metadata. However, the user can define in their application periodic time-events by inheriting from the TimedEvent class.

2.3. Functionalities

Fast DDS has some added features that can be implemented and configured by the user in their application. These are outlined below.

2.3.1. Discovery Protocols

The discovery protocols define the mechanisms by which DataWriters publishing under a given Topic, and DataReaders subscribing to that same Topic are matched, so that they can start sharing data. This applies at any point in the communication process. Fast DDS provides the following discovery mechanisms:

  • Simple Discovery. This is the default discovery mechanism, which is defined in the RTPS standard and provides compatibility with other DDS implementations. Here the DomainParticipants are discovered individually at an early stage to subsequently match the DataWriter and DataReader they implement.

  • Discovery Server. This discovery mechanism uses a centralized discovery architecture, where servers act as hubs for meta traffic discovery.

  • Static Discovery. This implements the discovery of DomainParticipants to each other but it is possible to skip the discovery of the entities contained in each DomainParticipant (DataReader/DataWriter) if these entities are known in advance by the remote DomainParticipants.

  • Manual Discovery. This mechanism is only compatible with the RTPS layer. It allows the user to manually match and unmatch RTPSParticipants, RTPSWriters, and RTPSReaders using whatever external meta-information channel of its choice.

The detailed explanation and configuration of all the discovery protocols implemented in Fast DDS can be seen in the Discovery section.

2.3.2. Security

Fast DDS can be configured to provide secure communications by implementing pluggable security at three levels:

  • Authentication of remote DomainParticipants. The DDS:Auth:PKI-DH plugin provides authentication using a trusted Certificate Authority (CA) and ECDSA Digital Signature Algorithms to perform the mutual authentication. It also establishes a shared secret using either Elliptic Curve Diffie-Hellman (ECDH) or MODP-2048 Diffie-Hellman (DH) as Key Agreement protocol.

  • Access control of entities. The DDS:Access:Permissions plugin provides access control to DomainParticipants at the DDS Domain and Topic level.

  • Encryption of data. The DDS:Crypto:AES-GCM-GMAC plugin provides authenticated encryption using Advanced Encryption Standard (AES) in Galois Counter Mode (AES-GCM).

More information about security configuration in Fast DDS is available in the Security section.

2.3.3. Logging

Fast DDS provides an extensible Logging system. Log class is the entry point of the Logging system. It exposes three macro definitions to ease its usage: EPROSIMA_LOG_INFO, EPROSIMA_LOG_WARNING and EPROSIMA_LOG_ERROR. Moreover, it allows the definition of new categories, in addition to those already available (INFO_MSG, WARN_MSG and ERROR_MSG). It provides filtering by category using regular expressions, as well as control of the verbosity of the Logging system. Details of the possible Logging system configurations can be found in the Logging section.

2.3.4. XML profiles configuration

Fast DDS offers the possibility to make changes in its default settings by using XML profile configuration files. Thus, the behavior of the DDS Entities can be modified without the need for the user to implement any program source code or re-build an existing application.

The user has XML tags for each of the API functionalities. Therefore, it is possible to build and configure DomainParticipant profiles through the <participant> tag, or the DataWriter and DataReader profiles with the <data_writer> and <data_reader> tags respectively.

For a better understanding of how to write and use these XML profiles configuration files you can continue reading the XML profiles section.

2.3.5. Environment variables

Environment variables are those variables that are defined outside the scope of the program, through operating system functionalities. Fast DDS relies on environment variables so that the user can easily customize the default settings of DDS applications. Please, refer to the Environment variables section for a complete list and description of the environment variables affecting Fast DDS.

3. DDS Layer

eProsima Fast DDS exposes two different APIs to interact with the communication service at different levels. The main API is the Data Distribution Service (DDS) Data-Centric Publish-Subscribe (DCPS) Platform Independent Model (PIM) API, or DDS DCPS PIM for short, which is defined by the Data Distribution Service (DDS) version 1.4 specification, to which Fast DDS complies. This section is devoted to explain the main characteristics and modes-of-use of this API under Fast DDS, providing an in depth explanation of the five modules into which it is divided:

3.1. Core

This module defines the infrastructure classes and types that will be used by the other ones. It contains the definition of Entity class, QoS policies, and Statuses.

  • Entity: An Entity is a DDS communication object that has a Status and can be configured with Policies.

  • Policy: Each of the configuration objects that govern the behavior of an Entity.

  • Status: Each of the objects associated with an Entity, whose values represent the communication status of that Entity.

3.1.1. Entity

Entity is the abstract base class for all the DDS entities, meaning an object that supports QoS policies, a listener, and statuses.

3.1.1.1. Types of Entities
  • DomainParticipant: This entity is the entry-point of the Service and acts as a factory for Publishers, Subscribers, and Topics. See DomainParticipant for further details.

  • Publisher: It acts as a factory that can create any number of DataWriters. See Publisher for further details.

  • Subscriber: It acts as a factory that can create any number of DataReaders. See Subscriber for further details.

  • Topic: This entity fits between the publication and subscription entities and acts as a channel. See Topic for further details.

  • DataWriter: Is the object responsible for the data distribution. See DataWriter for further details.

  • DataReader: Is the object used to access the received data. See DataReader for further details.

The following figure shows the hierarchy between all DDS entities:

_images/entity_diagram.svg
3.1.1.2. Common Entity Characteristics

All entity types share some characteristics that are common to the concept of an entity. Those are:

3.1.1.2.1. Entity Identifier

Each entity is identified by a unique ID, which is shared between the DDS entity and its corresponding RTPS entity if it exists. That ID is stored on an Instance Handle object declared on Entity base class, which can be accessed using the getter function get_instance_handle().

3.1.1.2.2. QoS policy

The behavior of each entity can be configured with a set of configuration policies. For each entity type, there is a corresponding Quality of Service (QoS) class that groups all the policies that affect said entity type. Users can create instances of these QoS classes, modify the contained policies to their needs, and use them to configure the entities, either during their creation or at a later time with the set_qos() function that every entity exposes (DomainParticipant::set_qos(), Publisher::set_qos(), Subscriber::set_qos(), Topic::set_qos(), DataWriter::set_qos(), DataReader::set_qos()). See Policy for a list of the available policies and their description. The QoS classes and the policies they contain are explained in the documentation for each entity type.

3.1.1.2.3. Listener

A listener is an object with functions that an entity will call in response to events. Therefore, the listener acts as an asynchronous notification system that allows the entity to notify the application about the Status changes in the entity.

All entity types define an abstract listener interface, which contains the callback functions that the entity will trigger to communicate the Status changes to the application. Users can implement their own listeners inheriting from these interfaces and implementing the callbacks that are needed on their application. Then they can link these listeners to each entity, either during their creation or at a later time with the set_listener() function that every entity exposes (DomainParticipant::set_listener(), Publisher::set_listener(), Subscriber::set_listener(), Topic::set_listener(), DataWriter::set_listener(), DataReader::set_listener()). The listener interfaces that each entity type and their callbacks are explained in the documentation for each entity type. When an event occurs it is handled by the lowest level entity with a listener that is non-null and has the corresponding callback enabled in its StatusMask. Higher level listeners inherit from the lower level ones as shown in the following diagram:

_images/listeners_inheritance_diagram.svg

Listeners inheritance diagram.

Note

The on_data_on_readers() callback intercepts messages before on_data_available(). This implies that if DomainParticipantListener is enabled, users should take into account that by default the listener uses StatusMask::all(). As the callback entity hierarchy is kept, the on_data_on_readers() is going to be called in this case. If an application wants to use on_data_available() instead, the corresponding bit of StatusMask should be disabled.

Warning

Only one thread is created to listen for every listener implemented, so it is encouraged to keep listener functions simple, leaving the process of such information to the proper class.

Warning

Do not create or delete any Entity within the scope of a Listener member function, since it could lead to an undefined behavior. It is recommended instead to use the Listener class as an information channel and the upper Entity class to encapsulate such behaviour.

3.1.1.2.4. Status

Each entity is associated with a set of status objects whose values represent the communication status of that entity. The changes on these status values are the ones that trigger the invocation of the appropriate Listener callback to asynchronously inform the application. See Status for a list of all the status objects and a description of their content. There you can also find which status applies to which entity type.

3.1.1.2.5. StatusCondition

Every entity owns a StatusCondition that will be notified whenever its enabled statuses change. The StatusCondition provides the link between an Entity and a Wait-set. See section Conditions and Wait-sets for more information.

3.1.1.2.6. Enabling Entities

All the entities can be created either enabled or not enabled. By default, the factories are configured to create the entities enabled, but it can be changed using the EntityFactoryQosPolicy on enabled factories. A disabled factory creates disabled entities regardless of its QoS. A disabled entity has its operations limited to the following ones:

  • Set/Get the entity QoS Policy.

  • Set/Get the entity Listener.

  • Create/Delete subentities.

  • Get the Status of the entity, even if they will not change.

  • Lookup operations.

Any other function called in this state will return NOT_ENABLED.

3.1.2. Policy

The Quality of Service (QoS) is used to specify the behavior of the Service, allowing the user to define how each entity will behave. To increase the flexibility of the system, the QoS is decomposed in several QoS Policies that can be configured independently. However, there may be cases where several policies conflict. Those conflicts are notified to the user through the ReturnCodes that the QoS setter functions returns.

Each Qos Policy has a unique ID defined in the QosPolicyId_t enumerator. This ID is used in some Status instances to identify the specific Qos Policy to which the Status refers.

There are QoS Policies that are immutable, which means that only can be specified either at the entity creation or before calling the enable operation.

Each DDS Entity has a specific set of QoS Policies that can be a mix of Standard QoS Policies, XTypes Extensions and eProsima Extensions.

3.1.2.1. Standard QoS Policies

This section explains each of the DDS standard QoS Policies:

3.1.2.1.1. DeadlineQosPolicy

This QoS policy raises an alarm when the frequency of new samples falls below a certain threshold. It is useful for cases where data is expected to be updated periodically (see DeadlineQosPolicy).

On the publishing side, the deadline defines the maximum period in which the application is expected to supply a new sample. On the subscribing side, it defines the maximum period in which new samples should be received.

For Topics with keys, this QoS is applied by key. Suppose that the positions of some vehicles have to be published periodically. In that case, it is possible to set the ID of the vehicle as the key of the data type and the deadline QoS to the desired publication period.

List of QoS Policy data members:

Data Member Name

Type

Default Value

period

Duration_t

c_TimeInfinite

Note

This QoS Policy applies to Topic, DataReader and DataWriter entities.
It can be changed on enabled entities.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

Compatibility Rule

To maintain the compatibility between DeadlineQosPolicy in DataReaders and DataWriters, the offered deadline period (configured on the DataWriter) must be less than or equal to the requested deadline period (configured on the DataReader), otherwise, the entities are considered to be incompatible.

The DeadlineQosPolicy must be set consistently with the TimeBasedFilterQosPolicy, which means that the deadline period must be higher or equal to the minimum separation.

Example
// This example uses a DataWriter, but it can also be applied to DataReader and Topic entities
DataWriterQos writer_qos;
// The DeadlineQosPolicy is constructed with an infinite period by default
// Change the period to 1 second
writer_qos.deadline().period.seconds = 1;
writer_qos.deadline().period.nanosec = 0;
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_deadline_profile">
    <qos>
        <deadline>
            <period>
                <sec>1</sec>
            </period>
        </deadline>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_deadline_profile">
    <qos>
        <deadline>
            <period>
                <sec>1</sec>
            </period>
        </deadline>
    </qos>
</data_reader>
3.1.2.1.2. DestinationOrderQosPolicy

Warning

This QoS Policy will be implemented in future releases.

Multiple DataWriters can send messages in the same Topic using the same key, and on the DataReader side all those messages are stored within the same instance of data (see DestinationOrderQosPolicy). This QoS policy controls the criteria used to determine the logical order of those messages. The behavior of the system depends on the value of the DestinationOrderQosPolicyKind.

List of QoS Policy data members:

Note

This QoS Policy applies to Topic, DataReader and DataWriter entities.
It cannot be changed on enabled entities.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

DestinationOrderQosPolicyKind

There are two possible values (see DestinationOrderQosPolicyKind):

  • BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS: This indicates that the data is ordered based on the reception time at each DataReader, which means that the last received value should be the one kept. This option may cause that each DataReader ends up with a different final value, since the DataReaders may receive the data at different times.

  • BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS: This indicates that the data is ordered based on the DataWriter timestamp at the time the message is sent. This option guarantees the consistency of the final value.

Both options depend on the values of the OwnershipQosPolicy and OwnershipStrengthQosPolicy, meaning that if the Ownership is set to EXCLUSIVE and the last value came from a DataWriter with low ownership strength, it will be discarded.

Compatibility Rule

To maintain the compatibility between DestinationOrderQosPolicy in DataReaders and DataWriters when they have different kind values, the DataWriter kind must be higher or equal to the DataReader kind. And the order between the different kinds is:

BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS < BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS

Table with the possible combinations:

3.1.2.1.3. DurabilityQosPolicy

A DataWriter can send messages throughout a Topic even if there are no DataReaders on the network. Moreover, a DataReader that joins to the Topic after some data has been written could be interested in accessing that information (see DurabilityQosPolicy).

The DurabilityQoSPolicy defines how the system will behave regarding those samples that existed on the Topic before the DataReader joins. The behavior of the system depends on the value of the DurabilityQosPolicyKind.

List of QoS Policy data members:

Data Member Name

Type

Default Value

kind

DurabilityQosPolicyKind

VOLATILE_DURABILITY_QOS for DataReaders
TRANSIENT_LOCAL_DURABILITY_QOS for DataWriters

Note

This QoS Policy applies to Topic, DataReader and DataWriter entities.
It cannot be changed on enabled entities.

Important

In order to receive past samples in the DataReader, besides setting this Qos Policy, it is required that the ReliabilityQosPolicy is set to RELIABLE_RELIABILITY_QOS.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

DurabilityQosPolicyKind

There are four possible values (see DurabilityQosPolicyKind):

Compatibility Rule

To maintain the compatibility between DurabilityQosPolicy in DataReaders and DataWriters when they have different kind values, the DataWriter kind must be higher or equal to the DataReader kind. And the order between the different kinds is:

VOLATILE_DURABILITY_QOS < TRANSIENT_LOCAL_DURABILITY_QOS < TRANSIENT_DURABILITY_QOS < PERSISTENT_DURABILITY_QOS

Table with the possible combinations:

Example
// This example uses a DataWriter, but it can also be applied to DataReader and Topic entities
DataWriterQos writer_qos;
// The DurabilityQosPolicy is constructed with kind = VOLATILE_DURABILITY_QOS by default
// Change the kind to TRANSIENT_LOCAL_DURABILITY_QOS
writer_qos.durability().kind = TRANSIENT_LOCAL_DURABILITY_QOS;
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_durability_profile">
    <qos>
        <durability>
            <kind>TRANSIENT_LOCAL</kind>
         </durability>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_durability_profile">
    <qos>
        <durability>
            <kind>VOLATILE</kind>
        </durability>
    </qos>
</data_reader>
3.1.2.1.4. DurabilityServiceQosPolicy

Warning

This QoS Policy will be implemented in future releases.

This QoS Policy is used to configure the HistoryQosPolicy and ResourceLimitsQosPolicy of the fictitious DataReader and DataWriter used when the DurabilityQosPolicy kind is set to TRANSIENT_DURABILITY_QOS or PERSISTENT_DURABILITY_QOS (see DurabilityServiceQosPolicy).

Those entities are used to simulate the persistent storage. The fictitious DataReader reads the data written on the Topic and stores it, so that if the user DataWriter does not have the information requested by the user DataReaders, the fictitious DataWriter takes care of sending that information.

List of QoS Policy data members:

Data Member Name

Type

Default Value

service_cleanup_delay

Duration_t

c_TimeZero

history_kind

HistoryQosPolicyKind

KEEP_LAST_HISTORY_QOS

history_depth

int32_t

1

max_samples

int32_t

-1 (Length Unlimited)

max_instances

int32_t

-1 (Length Unlimited)

max_samples_per_instance

int32_t

-1 (Length Unlimited)

  • service_cleanup_delay: It controls when the service can remove all the information regarding a data instance. That information is kept until all the following conditions are met:

    • The instance has been explicitly disposed and its InstanceState becomes NOT_ALIVE_DISPOSED_INSTANCE_STATE.

    • There is not any alive DataWriter writing the instance, which means that all existing writers either unregister the instance or lose their liveliness.

    • A time interval longer than the one established on the service_cleanup_delay has elapsed since the moment the service detected that the two previous conditions were met.

  • history_kind: Controls the kind of the HistoryQosPolicy associated with the Durability Service fictitious entities.

  • history_depth: Controls the depth of the HistoryQosPolicy associated with the Durability Service fictitious entities.

  • max_samples: Controls the maximum number of samples of the ResourceLimitsQosPolicy associated with the Durability Service fictitious entities. This value must be higher than the maximum number of samples per instance.

  • max_instances: Controls the maximum number of instances of the ResourceLimitsQosPolicy associated with the Durability Service fictitious entities.

  • max_samples_per_instance: Controls the maximum number of samples within an instance of the ResourceLimitsQosPolicy associated with the Durability Service fictitious entities. This value must be lower than the maximum number of samples.

Note

This QoS Policy applies to Topic and DataWriter entities.
It cannot be changed on enabled entities.

3.1.2.1.5. EntityFactoryQosPolicy

This QoS Policy controls the behavior of an Entity when it acts as a factory for other entities. By default, all the entities are created enabled, but if you change the value of the autoenable_created_entities to false, the new entities will be created disabled (see EntityFactoryQosPolicy).

List of QoS Policy data members:

Data Member Name

Type

Default Value

autoenable_created_entities

bool

true

Note

This QoS Policy applies to DomainParticipantFactory (as factory for DomainParticipant), DomainParticipant (as factory for Publisher, Subscriber and Topic), Publisher (as factory for DataWriter) and Subscriber (as factory for DataReader).
It can be changed on enabled entities, but it only affects those entities created after the change.

Example
// This example uses a Participant, but it can also be applied to
// DomainParticipantFactory, Publisher and Subscriber entities
DomainParticipantQos participant_qos;
// The EntityFactoryQosPolicy is constructed with autoenable_created_entities = true by default
// Change it to false
participant_qos.entity_factory().autoenable_created_entities = false;
// Use modified QoS in the creation of the corresponding entity
participant_ = factory_->create_participant(domain, participant_qos);

This QoS Policy cannot be configured using XML for the moment.

3.1.2.1.6. GroupDataQosPolicy

Allows the application to attach additional information to created Publishers or Subscribers. This data is common to all DataWriters/DataReaders belonging to the Publisher/Subscriber and it is propagated by means of the built-in topics (see GroupDataQosPolicy).

This QoS Policy can be used in combination with DataWriter and DataReader listeners to implement a matching policy similar to the PartitionQosPolicy.

List of QoS Policy data members:

Data Member Name

Type

Default Value

collection

std::vector<octet>

Empty vector

Note

This QoS Policy applies to Publisher and Subscriber entities.
It can be changed on enabled entities.

Example
// This example uses a Publisher, but it can also be applied to Subscriber entities
PublisherQos publisher_qos;
// The GroupDataQosPolicy is constructed with an empty collection by default
// Collection is a private member so you need to use getters and setters to access

// Add data to the collection in initialization
std::vector<eprosima::fastdds::rtps::octet> vec;
// Add two new octets to group data vector
eprosima::fastdds::rtps::octet val = 3;
vec.push_back(val);
val = 10;
vec.push_back(val);
publisher_qos.group_data().data_vec(vec); // Setter function
// Use modified QoS in the creation of the corresponding entity
publisher_ = participant_->create_publisher(publisher_qos);

// Add data to the collection at runtime
vec = publisher_qos.group_data().data_vec(); // Getter to keep old values
val = 31;
vec.push_back(val);
publisher_qos.group_data().data_vec(vec); // Setter function
// Update the QoS in the corresponding entity
publisher_->set_qos(publisher_qos);
<data_writer profile_name="writer_xml_conf_groupdata_profile">
    <qos>
        <groupData>
            <value>3.a</value>
        </groupData>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_groupdata_profile">
    <qos>
        <groupData>
            <value>3.a</value>
        </groupData>
    </qos>
</data_reader>
3.1.2.1.7. HistoryQosPolicy

This QoS Policy controls the behavior of the system when the value of an instance changes one or more times before it can be successfully communicated to the existing DataReader entities.

List of QoS Policy data members:

Data Member Name

Type

Default Value

kind

HistoryQosPolicyKind

KEEP_LAST_HISTORY_QOS

depth

int32_t

1

  • kind: Controls if the service should deliver only the most recent values, all the intermediate values or do something in between. See HistoryQosPolicyKind for further details.

  • depth: Establishes the maximum number of samples that must be kept on the history. It only has effect if the kind is set to KEEP_LAST_HISTORY_QOS and it needs to be consistent with the ResourceLimitsQosPolicy, which means that its value must be lower or equal to max_samples_per_instance.

Note

This QoS Policy applies to Topic, DataWriter and DataReader entities.
It cannot be changed on enabled entities.

HistoryQosPolicyKind

There are two possible values (see HistoryQosPolicyKind):

  • KEEP_LAST_HISTORY_QOS: The service will only attempt to keep the most recent values of the instance and discard the older ones. The maximum number of samples to keep and deliver is defined by the depth of the HistoryQosPolicy, which needs to be consistent with the ResourceLimitsQosPolicy settings. If the limit defined by depth is reached, the system will discard the oldest sample to make room for a new one.

  • KEEP_ALL_HISTORY_QOS: The service will attempt to keep all the values of the instance until it can be delivered to all the existing Subscribers. If this option is selected, the depth will not have any effect, so the history is only limited by the values set in ResourceLimitsQosPolicy.

Consistency rule

The HistoryQos must be set consistently with the ResourceLimitsQosPolicy, but also other QoS as DurabilityQosPolicy and ReliabilityQosPolicy, so there are several cases to take into account:

Example
// This example uses a DataWriter, but it can also be applied to DataReader and Topic entities
DataWriterQos writer_qos;
// The HistoryQosPolicy is constructed with kind = KEEP_LAST and depth = 1 by default
// It is possible to adjust the depth and keep the kind as KEEP_LAST
writer_qos.history().depth = 20;
// Or you can also change the kind to KEEP_ALL (depth will not be used).
writer_qos.history().kind = KEEP_ALL_HISTORY_QOS;
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<topic>
    <historyQos>
        <kind>KEEP_LAST</kind> <!-- string -->
        <depth>20</depth> <!-- uint32 -->
    </historyQos>
</topic>
3.1.2.1.8. LatencyBudgetQosPolicy

Warning

This QoS Policy will be implemented in future releases.

This QoS Policy specifies the maximum acceptable delay from the time the data is written until the data is inserted on the DataReader History and notified of the fact. That delay by default is set to 0 in order to optimize the internal operations (see LatencyBudgetQosPolicy).

List of QoS Policy data members:

Data Member Name

Type

Default Value

duration

Duration_t

c_TimeZero

Note

This QoS Policy applies to Topic, DataWriter and DataReader entities.
It can be changed on enabled entities.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

Compatibility Rule

To maintain the compatibility between LatencyBudgetQosPolicy in DataReaders and DataWriters, the DataWriter duration must be lower or equal to the DataReader duration.

3.1.2.1.9. LifespanQosPolicy

Each data sample written by a DataWriter has an associated expiration time beyond which the data is removed from the DataWriter and DataReader history as well as from the transient and persistent information caches (see LifespanQosPolicy).

By default, the duration is infinite, which means that there is not a maximum duration for the validity of the samples written by the DataWriter.

The expiration time is computed by adding the duration to the source timestamp, which can be calculated automatically if write() member function is called or supplied by the application by means of write_w_timestamp() member function. The DataReader is allowed to use the reception timestamp instead of the source timestamp.

List of QoS Policy data members:

Data Member Name

Type

Default Value

duration

Duration_t

c_TimeInfinite

Note

This QoS Policy applies to Topic, DataReader and DataWriter entities.
It can be changed on enabled entities.

Example
// This example uses a DataWriter, but it can also be applied to DataReader and Topic entities
DataWriterQos writer_qos;
// The LifespanQosPolicy is constructed with duration set to infinite by default
// Change the duration to 5 s
writer_qos.lifespan().duration = {5, 0};
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_lifespan_profile">
    <qos>
        <lifespan>
            <duration>
                <sec>5</sec>
            </duration>
        </lifespan>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_lifespan_profile">
    <qos>
        <lifespan>
            <duration>
                <sec>5</sec>
            </duration>
        </lifespan>
    </qos>
</data_reader>
3.1.2.1.10. LivelinessQosPolicy

This QoS Policy controls the mechanism used by the service to ensure that a particular entity on the network is still alive. There are different settings that allow distinguishing between applications where data is updated periodically and applications where data is changed sporadically. It also allows customizing the application regarding the kind of failures that should be detected by the liveliness mechanism (see LivelinessQosPolicy).

List of QoS Policy data members:

Note

This QoS Policy applies to Topic, DataReader and DataWriter entities.
It cannot be changed on enabled entities.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

LivelinessQosPolicyKind

There are three possible values (see LivelinessQosPolicyKind):

  • AUTOMATIC_LIVELINESS_QOS: The service takes the responsibility for renewing the leases at the required rates, as long as the local process where the participant is running and the link connecting it to remote participants exists, the entities within the remote participant will be considered alive. This kind is suitable for applications that only need to detect whether a remote application is still running.

  • The two Manual modes require that the application on the publishing side asserts the liveliness periodically before the lease_duration timer expires. Publishing any new data value implicitly asserts the DataWriter’s liveliness, but it can be done explicitly by calling the assert_liveliness member function.

    • MANUAL_BY_PARTICIPANT_LIVELINESS_QOS: If one of the entities in the publishing side asserts its liveliness, the service deduces that all other entities within the same DomainParticipant are also alive.

    • MANUAL_BY_TOPIC_LIVELINESS_QOS: This mode is more restrictive and requires that at least one instance within the DataWriter is asserted to consider that the DataWriter is alive.

Compatibility Rule

To maintain the compatibility between LivelinessQosPolicy in DataReaders and DataWriters, the DataWriter kind must be higher or equal to the DataReader kind. And the order between the different kinds is:

AUTOMATIC_LIVELINESS_QOS < MANUAL_BY_PARTICIPANT_LIVELINESS_QOS < MANUAL_BY_TOPIC_LIVELINESS_QOS

Table with the possible combinations:

Additionally, the lease_duration of the DataWriter must not be greater than the lease_duration of the DataReader.

Example
// This example uses a DataWriter, but it can also be applied to DataReader and Topic entities
DataWriterQos writer_qos;
// The LivelinessQosPolicy is constructed with kind = AUTOMATIC by default
// Change the kind to MANUAL_BY_PARTICIPANT
writer_qos.liveliness().kind = MANUAL_BY_PARTICIPANT_LIVELINESS_QOS;
// The LivelinessQosPolicy is constructed with lease_duration set to infinite by default
// Change the lease_duration to 1 second
writer_qos.liveliness().lease_duration = {1, 0};
// The LivelinessQosPolicy is constructed with announcement_period set to infinite by default
// Change the announcement_period to 1 ms
writer_qos.liveliness().announcement_period = {0, 1000000};
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_liveliness_profile">
    <qos>
        <liveliness>
            <announcement_period>
                <nanosec>1000000</nanosec>
            </announcement_period>
            <lease_duration>
                <sec>1</sec>
            </lease_duration>
            <kind>AUTOMATIC</kind>
        </liveliness>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_liveliness_profile">
    <qos>
        <liveliness>
            <lease_duration>
                <sec>1</sec>
            </lease_duration>
	    <kind>AUTOMATIC</kind>
        </liveliness>
    </qos>
</data_reader>
3.1.2.1.11. OwnershipQosPolicy

This QoS Policy specifies whether it is allowed for multiple DataWriters to update the same instance of data, and if so, how these modifications should be arbitrated (see OwnershipQosPolicy).

List of QoS Policy data members:

Data Member Name

Type

Default Value

kind

OwnershipQosPolicyKind

SHARED_OWNERSHIP_QOS

Note

This QoS Policy applies to Topic, DataReader and DataWriter entities.
It cannot be changed on enabled entities.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

OwnershipQosPolicyKind

There are two possible values (see OwnershipQosPolicyKind):

  • SHARED_OWNERSHIP_QOS: This option indicates that the service does not enforce unique ownership for each instance. In this case, multiple DataWriters are allowed to update the same data instance and all the updates are made available to the existing DataReaders. Those updates are also subject to the TimeBasedFilterQosPolicy or HistoryQosPolicy settings, so they can be filtered.

  • EXCLUSIVE_OWNERSHIP_QOS: This option indicates that each instance can only be updated by one DataWriter, meaning that at any point in time a single DataWriter owns each instance and is the only one whose modifications will be visible for the existing DataReaders. The owner can be changed dynamically according to the highest strength between the alive DataWriters, which has not violated the deadline contract concerning the data instances. That strength can be changed using the OwnershipStrengthQosPolicy. In case two DataWriters have the same strength value, the DataWriter with a lower GUID value would be the owner of the topic.

Compatibility Rule

To maintain the compatibility between OwnershipQosPolicy in DataReaders and DataWriters, the DataWriter kind must be equal to the DataReader kind.

Table with the possible combinations:

Example
// This example uses a DataWriter, but it can also be applied to DataReader and Topic entities
DataWriterQos writer_qos;
// The OwnershipQosPolicy is constructed with kind = SHARED by default
// Change the kind to EXCLUSIVE
writer_qos.ownership().kind = EXCLUSIVE_OWNERSHIP_QOS;
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_ownership_profile">
    <qos>
      <ownership>
	    <kind>EXCLUSIVE</kind>
      </ownership>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_ownership_profile">
    <qos>
        <ownership>
	    <kind>EXCLUSIVE</kind>
        </ownership>
    </qos>
</data_reader>
3.1.2.1.12. OwnershipStrengthQosPolicy

This QoS Policy specifies the value of the strength used to arbitrate among multiple DataWriters that attempt to modify the same data instance. It is only applicable if the OwnershipQosPolicy kind is set to EXCLUSIVE_OWNERSHIP_QOS. See OwnershipStrengthQosPolicy.

List of QoS Policy data members:

Data Member Name

Type

Default Value

value

uint32_t

0

Note

This QoS Policy applies to DataWriter entities.
It can be changed on enabled entities.

Example
// This example only applies to DataWriter entities
DataWriterQos writer_qos;
// The OwnershipStrengthQosPolicy is constructed with value 0 by default
// Change the strength to 10
writer_qos.ownership_strength().value = 10;
// Use modified QoS in the creation of the corresponding DataWriter
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_ownership_strength_profile">
    <qos>
        <ownershipStrength>
	    <value>10</value>
        </ownershipStrength>
    </qos>
</data_writer>
3.1.2.1.13. PartitionQosPolicy

This Qos Policy allows the introduction of a logical partition inside the physical partition introduced by a domain. For a DataReader to see the changes made by a DataWriter, not only the Topic must match, but also they have to share at least one logical partition (see PartitionQosPolicy).

The empty string is also considered as a valid partition and it matches with other partition names using the same rules of string matching and regular-expression matching used for any other partition name.

List of QoS Policy data members:

Data Member Name

Type

Default Value

max_size

uint32_t

0 (Length Unlimited)

names

SerializedPayload_t

Empty List

  • max_size: Maximum size for the list of partition names.

  • names: List of partition names.

Note

This QoS Policy applies to Publisher and Subscriber entities.
Partitions can also be explicitly defined at the endpoint level to override this configuration. Information to do so can be found here.
It can be changed on enabled entities.

Example
// This example uses a Publisher, but it can also be applied to Subscriber entities
PublisherQos publisher_qos;
// The PartitionsQosPolicy is constructed with max_size = 0 by default
// Max_size is a private member so you need to use getters and setters to access
// Change the max_size to 20
publisher_qos.partition().set_max_size(20); // Setter function
// The PartitionsQosPolicy is constructed with an empty list of partitions by default
// Partitions is a private member so you need to use getters and setters to access

// Add new partitions in initialization
std::vector<std::string> part;
part.push_back("part1");
part.push_back("part2");
publisher_qos.partition().names(part); // Setter function
// Use modified QoS in the creation of the corresponding entity
publisher_ = participant_->create_publisher(publisher_qos);

// Add data to the collection at runtime
part = publisher_qos.partition().names(); // Getter to keep old values
part.push_back("part3");
publisher_qos.partition().names(part); // Setter function
// Update the QoS in the corresponding entity
publisher_->set_qos(publisher_qos);
<data_writer profile_name="pub_partition_example">
    <qos>
        <partition>
            <names>
                <name>part1</name>
                <name>part2</name>
            </names>
        </partition>
    </qos>
</data_writer>

<data_reader profile_name="sub_partition_example">
    <qos>
        <partition>
            <names>
                <name>part1</name>
                <name>part2</name>
            </names>
        </partition>
    </qos>
</data_reader>
3.1.2.1.14. PresentationQosPolicy

Warning

This QoS Policy will be implemented in future releases.

This QoS Policy specifies how the samples representing changes to data instances are presented to the subscribing application. It controls the extent to which changes to data instances can be made dependent on each other, as well as the kind of dependencies that can be propagated and maintained. See PresentationQosPolicy.

List of QoS Policy data members:

  • access_scope: Determines the largest scope spanning the entities for which the order and coherency can be preserved. See PresentationQosPolicyAccessScopeKind for further details.

  • coherent_access: Controls whether the service will preserve grouping of changes made on the publishing side, such that they are received as a unit on the subscribing side.

  • ordered_access: Controls whether the service supports the ability of the subscriber to see changes in the same order as they occurred on the publishing side.

Note

This QoS Policy applies to Publisher and Subscriber entities.
It cannot be changed on enabled entities.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

PresentationQosPolicyAccessScopeKind

There are three possible values, which have different behaviors depending on the values of coherent_access and ordered_access variables (see PresentationQosPolicyAccessScopeKind):

  • INSTANCE_PRESENTATION_QOS: The changes to a data instance do not need to be coherent nor ordered with respect to the changes to any other instance, which means that the order and coherent changes apply to each instance separately.

    • Enabling the coherent_access, in this case, has no effect on how the subscriber can access the data as the scope is limited to each instance, changes to separate instances are considered independent and thus cannot be grouped by a coherent change.

    • Enabling the ordered_access, in this case, only affects to the changes within the same instance. Therefore, the changes made to two instances are not necessarily seen in the order they occur even if the same application thread and DataWriter made them.

  • TOPIC_PRESENTATION_QOS: The scope spans to all the instances within the same DataWriter.

    • Enabling the coherent_access makes that the grouping made with changes within the same DataWriter will be available as coherent with respect to other changes to instances in that DataWriter, but will not be grouped with changes made to instances belonging to different DataWriters.

    • Enabling the ordered_access means that the changes made by a single DataWriter are made available to the subscribers in the same order that they occur, but the changes made to instances through different DataWriters are not necessarily seen in order.

  • GROUP_PRESENTATION_QOS: The scope spans to all the instances belonging to DataWriters within the same Publisher.

    • Enabling the coherent_access, means that the coherent changes made to instances through DataWriters attached to a common Publisher are made available as a unit to remote subscribers.

    • Enabling the ordered_access with this scope makes that the changes done by any of the DataWriters attached to the same Publisher are made available to the subscribers in the same order they occur.

Compatibility Rule

To maintain the compatibility between PresentationQosPolicy in DataReaders and DataWriters, the Publisher access_scope must be higher or equal to the Subscriber access_scope. And the order between the different access scopes is:

|INSTANCE_PRESENTATION_QOS-api| < |TOPIC_PRESENTATION_QOS-api| < |GROUP_PRESENTATION_QOS-api|

Table with the possible combinations:

Additionally, the coherent_access and ordered_access of the Subscriber can only be enabled if they are also enabled on the Publisher.

3.1.2.1.15. ReaderDataLifecycleQosPolicy

Warning

This QoS Policy will be implemented in future releases.

This QoS Policy specifies the behavior of the DataReader with respect to the lifecycle of the data instances it manages, that is, the instances that have been received and for which the DataReader maintains some internal resources. The DataReader maintains the samples that have not been taken by the application, subject to the constraints imposed by HistoryQosPolicy and ResourceLimitsQosPolicy. See ReaderDataLifecycleQosPolicy.

Under normal circumstances, the DataReader can only reclaim the resources associated with data instances if there are no writers and all the samples have been taken. But this fact can cause problems if the application does not take those samples as the service will prevent the DataReader from reclaiming the resources and they will remain in the DataReader indefinitely. This QoS exist to avoid that situation.

List of QoS Policy data members:

Data Member Name

Type

Default Value

autopurge_no_writer_samples_delay

Duration_t

c_TimeInfinite

autopurge_disposed_samples_delay

Duration_t

c_TimeInfinite

Note

This QoS Policy applies to DataReader entities.
It can be changed on enabled entities.

3.1.2.1.16. ReliabilityQosPolicy

This QoS Policy indicates the level of reliability offered and requested by the service. See ReliabilityQosPolicy.

List of QoS Policy data members:

Data Member Name

Type

Default Value

kind

ReliabilityQosPolicyKind

BEST_EFFORT_RELIABILITY_QOS for DataReaders
RELIABLE_RELIABILITY_QOS for DataWriters

max_blocking_time

Duration_t

100 ms

Note

This QoS Policy applies to Topic, DataWriter and DataReader entities.
It cannot be changed on enabled entities.

Important

Setting this QoS Policy to BEST_EFFORT_RELIABILITY_QOS affects to the DurabilityQosPolicy, making the endpoints behave as VOLATILE_DURABILITY_QOS.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

ReliabilityQosPolicyKind

There are two possible values ():

  • BEST_EFFORT_RELIABILITY_QOS: It indicates that it is acceptable not to retransmit the missing samples, so the messages are sent without waiting for an arrival confirmation. Presumably new values for the samples are generated often enough that it is not necessary to re-send any sample. However, the data samples sent by the same DataWriter will be stored in the DataReader history in the same order they occur. In other words, even if the DataReader misses some data samples, an older value will never overwrite a newer value.

  • RELIABLE_RELIABILITY_QOS: It indicates that the service will attempt to deliver all samples of the DataWriter’s history expecting an arrival confirmation from the DataReader. The data samples sent by the same DataWriter cannot be made available to the DataReader if there are previous samples that have not been received yet. The service will retransmit the lost data samples in order to reconstruct a correct snapshot of the DataWriter history before it is accessible by the DataReader.

    This option may block the write operation, hence the max_blocking_time is set that will unblock it once the time expires. But if the max_blocking_time expires before the data is sent, the write operation will return an error.

Compatibility Rule

To maintain the compatibility between ReliabilityQosPolicy in DataReaders and DataWriters, the DataWriter kind must be higher or equal to the DataReader kind. And the order between the different kinds is:

BEST_EFFORT_RELIABILITY_QOS < RELIABLE_RELIABILITY_QOS

Table with the possible combinations:

Example
// This example uses a DataWriter, but it can also be applied to DataReader and Topic entities
DataWriterQos writer_qos;
// The ReliabilityQosPolicy is constructed with kind = BEST_EFFORT by default
// Change the kind to RELIABLE
writer_qos.reliability().kind = RELIABLE_RELIABILITY_QOS;
// The ReliabilityQosPolicy is constructed with max_blocking_time = 100ms by default
// Change the max_blocking_time to 1s
writer_qos.reliability().max_blocking_time = {1, 0};
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_reliability_profile">
    <qos>
        <reliability>
            <kind>RELIABLE</kind>
            <max_blocking_time>
                <sec>1</sec>
            </max_blocking_time>
        </reliability>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_reliability_profile">
    <qos>
        <reliability>
            <kind>BEST_EFFORT</kind>
        </reliability>
    </qos>
</data_reader>
3.1.2.1.17. ResourceLimitsQosPolicy

This QoS Policy controls the resources that the service can use in order to meet the requirements imposed by the application and other QoS Policies. See ResourceLimitsQosPolicy.

List of QoS Policy data members:

Data Member Name

Type

Default Value

max_samples

int32_t

5000

max_instances

int32_t

10

max_samples_per_instance

int32_t

400

allocated_samples

int32_t

100

extra_samples

int32_t

1

  • max_samples: Controls the maximum number of samples that the DataWriter or DataReader can manage across all the instances associated with it. In other words, it represents the maximum samples that the middleware can store for a DataReader or DataWriter. Value less or equal to 0 means infinite resources.

  • max_instances: Controls the maximum number of instances that a DataWriter or DataReader can manage. Value less or equal to 0 means infinite resources.

  • max_samples_per_instance: Controls the maximum number of samples within an instance that the DataWriter or DataReader can manage. Value less or equal to 0 means infinite resources.

  • allocated_samples: States the number of samples that will be allocated on initialization.

  • extra_samples: States the number of extra samples that will be allocated on the pool, so the maximum number of samples on the pool will be max_samples plus extra_samples. These extra samples act as a reservoir of samples even when the history is full.

Note

This QoS Policy applies to Topic, DataWriter and DataReader entities.
It cannot be changed on enabled entities.

Consistency Rule

To maintain the consistency within the ResourceLimitsQosPolicy, the values of the data members must follow the next conditions:

Example
// This example uses a DataWriter, but it can also be applied to DataReader and Topic entities
DataWriterQos writer_qos;
// The ResourceLimitsQosPolicy is constructed with max_samples = 5000 by default
// Change max_samples to 2000
writer_qos.resource_limits().max_samples = 2000;
// The ResourceLimitsQosPolicy is constructed with max_instances = 10 by default
// Change max_instances to 20
writer_qos.resource_limits().max_instances = 20;
// The ResourceLimitsQosPolicy is constructed with max_samples_per_instance = 400 by default
// Change max_samples_per_instance to 100
writer_qos.resource_limits().max_samples_per_instance = 100;
// The ResourceLimitsQosPolicy is constructed with allocated_samples = 100 by default
// Change allocated_samples to 50
writer_qos.resource_limits().allocated_samples = 50;
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_resource_limits_profile">
    <topic>
        <resourceLimitsQos>
            <max_samples>2000</max_samples>
            <max_instances>20</max_instances>
            <max_samples_per_instance>100</max_samples_per_instance>
            <allocated_samples>50</allocated_samples>
        </resourceLimitsQos>
    </topic>
</data_writer>

<data_reader profile_name="reader_xml_conf_resource_limits_profile">
    <topic>
        <resourceLimitsQos>
            <max_samples>2000</max_samples>
            <max_instances>20</max_instances>
            <max_samples_per_instance>100</max_samples_per_instance>
            <allocated_samples>50</allocated_samples>
        </resourceLimitsQos>
    </topic>
</data_reader>
3.1.2.1.18. TimeBasedFilterQosPolicy

Warning

This QoS Policy will be implemented in future releases.

Filter that allows a DataReader to specify that it is interested only in a subset of the values of the data. This filter states that the DataReader does not want to receive more than one value each minimum_separation, regardless of how fast the changes occur. See TimeBasedFilterQosPolicy.

The minimum_separation must be lower than the DeadlineQosPolicy period. By default, the minimum_separation is zero, which means that the DataReader is potentially interested in all the values.

List of QoS Policy data members:

Data Member Name

Type

Default Value

minimum_separation

Duration_t

c_TimeZero

Note

This QoS Policy applies to DataReader entities.
It can be changed on enabled entities.

3.1.2.1.19. TopicDataQosPolicy

Allows the application to attach additional information to a created Topic so that when it is discovered by a remote application, it can access the data and use it. See TopicDataQosPolicy.

List of QoS Policy data members:

Data Member Name

Type

Default Value

collection

std::vector<octet>

Empty vector

Note

This QoS Policy applies to Topic entities.
It can be changed even if it is already created.

Example
// This example only applies to Topic entities
TopicQos topic_qos;
// The TopicDataQosPolicy is constructed with an empty vector by default
std::vector<eprosima::fastdds::rtps::octet> vec;
// Add two new octets to topic data vector
eprosima::fastdds::rtps::octet val = 3;
vec.push_back(val);
val = 10;
vec.push_back(val);
topic_qos.topic_data().data_vec(vec); // Setter Function
// Use modified QoS in the creation of the corresponding Topic
topic_ = participant_->create_topic("<topic_name>", "<type_name>", topic_qos);
<data_writer profile_name="writer_xml_conf_topicdata_profile">
    <qos>
        <topicData>
            <value>3.a</value>
        </topicData>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_topicdata_profile">
    <qos>
        <topicData>
            <value>3.a</value>
        </topicData>
    </qos>
</data_reader>
3.1.2.1.20. TransportPriorityQosPolicy

Warning

This QoS Policy will be implemented in future releases.

The purpose of this QoS Policy is to allow the service to take advantage of those transports capable of sending messages with different priorities. It establishes the priority of the underlying transport used to send the data. See TransportPriorityQosPolicy

You can choose any value within the 32-bit range for the priority. The higher the value, the higher the priority.

List of QoS Policy data members:

Data Member Name

Type

Default Value

value

uint32_t

0

Note

This QoS Policy applies to Topic and DataWriter entities.
It can be changed on enabled entities.

3.1.2.1.21. UserDataQosPolicy

Allows the application to attach additional information to the Entity object so that when the entity is discovered the remote application can access the data and use it. For example, it can be used to attach the security credentials to authenticate the source from the remote application. See UserDataQosPolicy.

List of QoS Policy data members:

Data Member Name

Type

Default Value

collection

std::vector<octet>

Empty vector

Note

This QoS Policy applies to DomainParticipant, DataWriter and DataReader entities.
It can be changed on enabled entities.

Example
// This example uses a DataWriter, but it can also be applied to DomainParticipant and DataReader entities
DataWriterQos writer_qos;
std::vector<eprosima::fastdds::rtps::octet> vec;
// Add two new octets to user data vector
eprosima::fastdds::rtps::octet val = 3;
vec.push_back(val);
val = 10;
vec.push_back(val);
writer_qos.user_data().data_vec(vec); // Setter Function
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<participant profile_name="participant_xml_conf_userdata_profile">
    <rtps>
        <userData>
            <value>3.a</value>
        </userData>
    </rtps>
</participant>

<data_writer profile_name="writer_xml_conf_userdata_profile">
    <qos>
        <userData>
            <value>3.a</value>
        </userData>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_userdata_profile">
    <qos>
        <userData>
            <value>3.a</value>
        </userData>
    </qos>
</data_reader>
3.1.2.1.22. WriterDataLifecycleQosPolicy

Warning

This QoS Policy will be implemented in future releases.

This QoS Policy specifies the behavior of the DataWriter with respect to the lifecycle of the data instances it manages , that is, the instance that has been either explicitly registered with the DataWriter using the register operations or implicitly by directly writing data.

The autodispose_unregistered_instances controls whether a DataWriter will automatically dispose an instance each time it is unregistered. Even if it is disabled, the application can still get the same result if it uses the dispose operation before unregistering the instance.

List of QoS Policy data members:

Data Member Name

Type

Default Value

autodispose_unregistered_instances

bool

true

Note

This QoS Policy applies to DataWriter entities.
It can be changed on enabled entities.

3.1.2.2. eProsima Extensions

The eProsima QoS Policies extensions are those that allow changing the values of the RTPS layer configurable settings.

3.1.2.2.1. DataSharingQosPolicy

This additional QoS allows configuring the data-sharing delivery communication between a writer and a reader. Please, see Data-sharing delivery for a description of the data-sharing delivery functionality.

List of QoS Policy data members:

Data Member

Type

Accessor

Default Value

Data-sharing kind

DataSharingKind

kind()

AUTO

Shared memory directory

string

shm_directory()

Empty string

Maximum domain number

uint32_t

max_domains()

0 (unlimited)

Data-sharing domain IDs

vector<uint64_t>

domain_ids()

Empty

Data-sharing listener thread settings

ThreadSettings

data_sharing_listener_thread()

  • Data-sharing kind: Specifies the behavior of data-sharing delivery. See DataSharingKind for a description of possible values and their effect.

  • Shared memory directory: The directory that will be used for the memory-mapped files. If none is configured, then the system default directory will be used.

  • Maximum domain number: Establishes the maximum number of data-sharing domain IDs in the local or remote endpoints. Domain IDs are exchanged between data-sharing delivery compatible endpoints. If this value is lower that the size of the list for any remote endpoint, the matching may fail. A value of zero represents unlimited number of IDs.

  • Data sharing domain IDs: The list of data-sharing domain IDs configured for the current DataWriter or DataReader. If no ID is provided, the system will create a unique one for the current machine.

  • Data-sharing listener thread settings: The ThreadSettings for the data-sharing thread dedicated to listening for incoming traffic.

Note

This QoS Policy applies to DataWriter and DataReader entities.
It cannot be changed on enabled entities.

DataSharingKind

There are three possible values (see DataSharingKind):

  • OFF: The data-sharing delivery is disabled. No communication will be performed using data-sharing delivery functionality.

  • ON: The data-sharing delivery is manually enabled. An error will occur if the current topic is not compatible with data-sharing delivery. Communication with remote entities that share at least one data-sharing domain ID will be done using data-sharing delivery functionality.

  • AUTO: data-sharing delivery will be activated if the current topic is compatible with data-sharing, and deactivated if not.

Data-sharing configuration helper functions

In order to set the data-sharing delivery configuration, one of the following helper member functions must be used. There is one for each DataSharingKind flavor:

Function

Resulting DataSharingKind

Shared memory directory

Data sharing domain IDs

automatic()

AUTO

Optional

Optional

on()

ON

Mandatory

Optional

off()

OFF

N/A

N/A

Instead of defining the data-sharing domain IDs on these helper functions, you can add them later with the add_domain_id() function. Beware that adding a new domain ID counts as modifying the QosPolicy, so it must be done before the entity is enabled.

Example
// This example uses a DataWriter, but it can also be applied to DataReader entities
DataWriterQos writer_qos;

// DataSharing is set to AUTO by default, which means that DataSharing will be used if the topic
// is compatible. If no Shared Memory directory is specified, the default one will be used.

// Configure DataSharing to ON to enable DataSharing and specify the shared memory directory (mandatory)
writer_qos.data_sharing().on("/path/to/shared_memory/directory");
// Alternatively, configure DataSharing to OFF to disable it
writer_qos.data_sharing().off();

// Configure the DataSharing as AUTO with two user-defined IDs (can also be used with ON)
std::vector<uint16_t> ids;
ids.push_back(0x1234);
ids.push_back(0xABCD);
writer_qos.data_sharing().automatic(ids);

// Alternatively, add them individually
writer_qos.data_sharing().add_domain_id(uint16_t(0x1234));
writer_qos.data_sharing().add_domain_id(uint16_t(0xABCD));
// Or you can leave the IDs empty and the system will automatically create a
// unique ID for the current machine

// Set the maximum number of domains to 5. Setting 0 means 'unlimited'
writer_qos.data_sharing().set_max_domains(5);

// [OPTIONAL] ThreadSettings for listening thread
writer_qos.data_sharing().data_sharing_listener_thread(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});

// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<?xml version="1.0" encoding="UTF-8" ?>
<dds>
    <profiles xmlns="http://www.eprosima.com">
        <data_writer profile_name="writer_profile_qos_datasharing">
            <qos>
                <data_sharing>
                    <kind>AUTOMATIC</kind>
                    <domain_ids>
                        <domainId>123</domainId>
                        <domainId>098</domainId>
                    </domain_ids>
                </data_sharing>
            </qos>
        </data_writer>

        <data_reader profile_name="reader_profile_qos_datasharing">
            <qos>
                <data_sharing>
                    <kind>AUTOMATIC</kind>
                    <domain_ids>
                        <domainId>123</domainId>
                        <domainId>098</domainId>
                    </domain_ids>
                    <data_sharing_listener_thread>
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </data_sharing_listener_thread>
                </data_sharing>
            </qos>
        </data_reader>
    </profiles>
<dds>
3.1.2.2.2. DisablePositiveACKsQosPolicy

This additional QoS allows reducing network traffic when strict reliable communication is not required and bandwidth is limited. It consists in changing the default behavior by which positive acks are sent from readers to writers. Instead, only negative acks will be sent when a reader is missing a sample, but writers will keep data for an adjustable time before considering it as acknowledged. See DisablePositiveACKsQosPolicy.

List of QoS Policy data members:

Data Member Name

Type

Default Value

enabled

bool

false

duration

Duration_t

c_TimeInfinite

  • enabled: Specifies if the QoS is enabled or not. If it is true means that the positive acks are disabled and the DataReader only sends negative acks. Otherwise, both positive and negative acks are sent.

  • duration: State the duration that the DataWriters keep the data before considering it as acknowledged. This value does not apply to DataReaders.

Note

This QoS Policy applies to DataWriter and DataReader entities.
The enabled Data Member cannot be modified on enabled entities. Thus, this feature must be set up during initialization. Only the duration Data Member can be modified at runtime.

Warning

For DataWriters and DataReaders to match, they must follow the compatibility rule. See Compatibility Rule for further details.

Compatibility Rule

To maintain the compatibility between DisablePositiveACKsQosPolicy in DataReaders and DataWriters, the DataReader cannot have this QoS enabled if the DataWriter have it disabled.

Table with the possible combinations:

DataWriter enabled value

DataReader enabled value

Compatibility

true

true

Yes

true

false

Yes

false

true

No

false

false

Yes

Example
// This Qos has different API for DataWriter and DataReader entities, because it is accesed
// through the ReliableWriterQos and ReliableReaderQos respectively.
// For further details see RTPSReliableWriterQos & RTPSReliableReaderQos sections.
DataWriterQos writer_qos;
DataReaderQos reader_qos;
// The DisablePositiveACKsQosPolicy is constructed with enabled = false by default
// Change enabled to true
writer_qos.reliable_writer_qos().disable_positive_acks.enabled = true;
reader_qos.reliable_reader_qos().disable_positive_acks.enabled = true;
// The DisablePositiveACKsQosPolicy is constructed with infinite duration by default
// Change the duration to 1 second
writer_qos.reliable_writer_qos().disable_positive_acks.duration = {1, 0};
reader_qos.reliable_reader_qos().disable_positive_acks.duration = {1, 0};

// Exclusively, DataWriters can additionally disable the heartbeat piggyback
writer_qos.reliable_writer_qos().disable_heartbeat_piggyback = true;

// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
reader_ = subscriber_->create_datareader(topic_, reader_qos);
<data_writer profile_name="writer_xml_conf_disable_positive_acks_profile">
    <qos>
        <disablePositiveAcks>
            <enabled>true</enabled>
            <duration>
                <sec>1</sec>
            </duration>
        </disablePositiveAcks>
    </qos>
</data_writer>

<data_reader profile_name="reader_xml_conf_disable_positive_acks_profile">
    <qos>
        <disablePositiveAcks>
            <enabled>true</enabled>
        </disablePositiveAcks>
    </qos>
</data_reader>
3.1.2.2.3. RTPSReliableReaderQos

This RTPS QoS Policy allows the configuration of several RTPS reliable reader’s aspects. See RTPSReliableReaderQos.

List of QoS Policy data members:

Note

This QoS Policy applies to DataReader entities.
Only the duration Data Member of the DisablePositiveACKsQosPolicy and the times Data Member can be modified on enabled entities.

ReaderTimes

This structure defines the times associated with the Reliable Readers’ events. See ReaderTimes.

List of structure members:

Member Name

Type

Default Value

initial_acknack_delay

Duration_t

70 ms

heartbeat_response_delay

Duration_t

5 ms

Example
// This example only applies to DataReader entities
DataReaderQos reader_qos;
// The RTPSReliableReaderQos is constructed with initial_acknack_delay = 70 ms by default
// Change the initialAcknackDelay to 70 nanoseconds
reader_qos.reliable_reader_qos().times.initial_acknack_delay = {0, 70};
// The RTPSReliableReaderQos is constructed with heartbeat_response_delay = 5 ms by default
// Change the heartbeatResponseDelay to 5 nanoseconds
reader_qos.reliable_reader_qos().times.heartbeat_response_delay = {0, 5};
// You can also change the DisablePositiveACKsQosPolicy. For further details see DisablePositiveACKsQosPolicy section.
reader_qos.reliable_reader_qos().disable_positive_acks.enabled = true;
// Use modified QoS in the creation of the DataReader entity
reader_ = subscriber_->create_datareader(topic_, reader_qos);
<data_reader profile_name="sub_profile_name">
    <times> <!-- readerTimesType -->
        <initial_acknack_delay> <!-- DURATION -->
            <nanosec>70</nanosec>
        </initial_acknack_delay>
        <heartbeat_response_delay> <!-- DURATION -->
            <nanosec>5</nanosec>
        </heartbeat_response_delay>
    </times>
    <!--You can also change the values of DisablePositiveACKsQosPolicy.-->
    <!--See DisablePositiveACKsQosPolicy section for further details-->
</data_reader>
3.1.2.2.4. RTPSReliableWriterQos

This RTPS QoS Policy allows the configuration of several RTPS reliable writer’s aspects. See RTPSReliableWriterQos.

List of QoS Policy data members:

Note

This QoS Policy applies to DataWriter entities.
Only the duration Data Member of the DisablePositiveACKsQosPolicy and the times Data Member can be modified on enabled entities.

WriterTimes

This structure defines the times associated with the Reliable Writers’ events.

List of structure members:

Member Name

Type

Default Value

initial_heartbeat_delay

Duration_t

12ms

heartbeat_period

Duration_t

3s

nack_response_delay

Duration_t

5ms

nack_supression_duration

Duration_t

0s

DisableHeartbeatPiggyback

Besides sending heartbeats periodically using the heartbeat_period (see WriterTimes), reliable DataWriters also use a mechanism to append a heartbeat submessage in the same message where data is being delivered to the DataReaders. This mechanism acts in specific situations where the reliable communication state must be up to date to maintain optimal communication:

  • When the DataWriter sends as many bytes to the socket as the length of the socket buffer, a heartbeat submessage is appended after the last data.

  • When the DataWriter’s history is full, the DataWriter starts to append heartbeat submessages after each data.

This mechanism can be disabled using this policy.

Example
// This example only applies to DataWriter entities
DataWriterQos writer_qos;
// The RTPSReliableWriterQos is constructed with initial_heartbeat_delay = 12 ms by default
// Change the initial_heartbeat_delay to 20 nanoseconds
writer_qos.reliable_writer_qos().times.initial_heartbeat_delay = {0, 20};
// The RTPSReliableWriterQos is constructed with heartbeat_period = 3 s by default
// Change the heartbeat_period to 5 seconds
writer_qos.reliable_writer_qos().times.heartbeat_period = {5, 0};
// The RTPSReliableWriterQos is constructed with nack_response_delay = 5 ms by default
// Change the nack_response_delay to 10 nanoseconds
writer_qos.reliable_writer_qos().times.nack_response_delay = {0, 10};
// The RTPSReliableWriterQos is constructed with nack_supression_duration = 0 s by default
// Change the nack_supression_duration to 20 nanoseconds
writer_qos.reliable_writer_qos().times.nack_supression_duration = {0, 20};
// You can also change the DisablePositiveACKsQosPolicy. For further details see DisablePositiveACKsQosPolicy section.
writer_qos.reliable_writer_qos().disable_positive_acks.enabled = true;
// The RTPSReliableWriterQos is constructed with disable_heartbeat_piggyback = false by default
// Disable the heartbeat piggyback mechanism.
writer_qos.reliable_writer_qos().disable_heartbeat_piggyback = true;
// Use modified QoS in the creation of the DataWriter entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="pub_profile_name">
    <times> <!-- writerTimesType -->
        <initial_heartbeat_delay> <!-- DURATION -->
            <nanosec>20</nanosec>
        </initial_heartbeat_delay>
        <heartbeat_period> <!-- DURATION -->
            <sec>5</sec>
        </heartbeat_period>
        <nack_response_delay> <!-- DURATION -->
            <nanosec>10</nanosec>
        </nack_response_delay>
        <nack_supression_duration> <!-- DURATION -->
            <nanosec>20</nanosec>
        </nack_supression_duration>
    </times>

    <!--You can also change the values of DisablePositiveACKsQosPolicy.-->
    <!--See DisablePositiveACKsQosPolicy section for further details-->
    <qos>
        <!--Disable heartbeat piggyback mechanism.-->
        <disable_heartbeat_piggyback>true</disable_heartbeat_piggyback>
    </qos>
</data_writer>
3.1.2.2.5. FlowControllersQos

This QoS configures the list of flow controllers of a participant, so they can later be used on its DataWriters. It is a vector of shared pointers to FlowControllerDescriptor, which has the following fields:

Data Member Name

Type

Default Value

name

string

scheduler

FlowControllerSchedulerPolicy

FIFO_SCHED_POLICY-api|

max_bytes_per_period

int32_t

0 (i.e. infinite)

period_ms

uint64_t

100

sender_thread

ThreadSettings

Please refer to Flow Controllers section for more information.

Note

This QoS Policy applies to DomainParticipant entities.
It cannot be changed on enabled entities.

3.1.2.2.6. ParticipantResourceLimitsQos

This QoS configures allocation limits and the use of physical memory for internal resources.

List of QoS Policy data members:

  • locators: Defines the limits for collections of remote locators.

  • participants: Specifies the allocation behavior and limits for collections dependent on the total number of participants.

  • readers: Specifies the allocation behavior and limits for collections dependent on the total number of readers per participant.

  • writers: Specifies the allocation behavior and limits for collections dependent on the total number of writers per participant.

  • send_buffers: Defines the allocation behavior and limits for the send buffer manager.

  • data_limits: States the limits for variable-length data.

  • content_filter: States the limits for content-filter discovery information.

Note

This QoS Policy applies to DomainParticipant entities.
It cannot be changed on enabled entities.

RemoteLocatorsAllocationAttributes

This structure holds the limits for the remote locators’ collections. See RemoteLocatorsAllocationAttributes.

List of structure members:

Member Name

Type

Default Value

max_unicast_locators

size_t

4

max_multicast_locators

size_t

1

  • max_unicast_locators: This member controls the maximum number of unicast locators to keep for each discovered remote entity. It is recommended to use the highest number of local addresses found on all the systems belonging to the same domain.

  • max_multicast_locators: This member controls the maximum number of multicast locators to keep for each discovered remote entity. The default value is usually enough, as it does not make sense to add more than one multicast locator per entity.

ResourceLimitedContainerConfig

This structure holds the limits of a resource limited collection, as well as the allocation configuration, which can be fixed size or dynamic size.

List of structure members:

Member Name

Type

Default Value

initial

size_t

0

maximum

size_t

std::numeric_limits<size_t>::max()

increment

size_t

1 (dynamic size), 0 (fixed size)

  • initial: Indicates the number of elements to preallocate in the collection.

  • maximum: Specifies the maximum number of elements allowed in the collection.

  • increment: States the number of items to add when the reserved capacity limit is reached. This member has a different default value depending on the allocation configuration chosen.

SendBuffersAllocationAttributes

This structure holds the limits for the allocations of the send buffers. See SendBuffersAllocationAttributes.

List of structure members:

Member Name

Type

Default Value

preallocated_number

size_t

0

dynamic

bool

false

network_buffers_config

ResourceLimitedContainerConfig

(16, inf, 16)

  • preallocated_number: This member controls the initial number of send buffers to be allocated. The default value will perform an initial guess of the number of buffers required, based on the number of threads from which a send operation could be started.

  • dynamic: This member controls how the buffer manager behaves when a send buffer is not available. When true, a new buffer will be created. Otherwise, it will wait for a buffer to be returned.

  • network_buffers_config: This attribute defines the allocation behavior and limits of the network buffers contained in each send buffer. The default value will preallocate 16 network buffers and dynamically allocate 16 network buffers every time that growing the vector is needed.

Note

network_buffers_config will also be used to instantiate a vector of SerializedPayload_t that contains the metadata necessary to avoid payload copies during the creation of the RTPS message.

VariableLengthDataLimits

This structure holds the limits for variable-length data. See VariableLengthDataLimits.

List of structure members:

Member Name

Type

Default Value

max_properties

size_t

0

max_user_data

size_t

0

max_partitions

size_t

0

  • max_properties: Defines the maximum size, in octets, of the properties data in the local or remote participant.

  • max_user_data: Establishes the maximum size, in octets, of the user data in the local or remote participant.

  • max_partitions: States the maximum size, in octets, of the partitions data in the local or remote participant.

ContentFilterProperty::AllocationConfiguration

This structure holds the limits for content-filter related discovery information. See ContentFilterProperty::AllocationConfiguration.

List of structure members:

Member Name

Type

Default Value

expression_initial_size

size_t

0

expression_parameters

ResourceLimitedContainerConfig

{0, 100, 1}

Example
// This example only applies to DomainParticipant entities
DomainParticipantQos participant_qos;
// Set the maximum size of participant resource limits collection to 3 and it allocation configuration to fixed size
participant_qos.allocation().participants =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(
    3u);
// Set the maximum size of reader's resource limits collection to 2 and its allocation configuration to fixed size
participant_qos.allocation().readers =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(2u);
// Set the maximum size of writer's resource limits collection to 1 and its allocation configuration to fixed size
participant_qos.allocation().writers =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(1u);
// Set the maximum size of the partition data to 256
participant_qos.allocation().data_limits.max_partitions = 256u;
// Set the maximum size of the user data to 256
participant_qos.allocation().data_limits.max_user_data = 256u;
// Set the maximum size of the properties data to 512
participant_qos.allocation().data_limits.max_properties = 512u;
// Set the preallocated filter expression size to 512
participant_qos.allocation().content_filter.expression_initial_size = 512u;
// Set the maximum number of expression parameters to 4 and its allocation configuration to fixed size
participant_qos.allocation().content_filter.expression_parameters =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(4u);
// Use modified QoS in the creation of the corresponding DomainParticipant
participant_ = factory_->create_participant(domain, participant_qos);
<participant profile_name="participant_alloc_qos_example">
    <rtps>
        <allocation>
            <!-- We know we have 3 participants on the domain -->
            <total_participants>
                <initial>3</initial>
                <maximum>3</maximum>
                <increment>0</increment>
            </total_participants>
            <!-- We know we have at most 2 readers on each participant -->
            <total_readers>
                <initial>2</initial>
                <maximum>2</maximum>
                <increment>0</increment>
            </total_readers>
            <!-- We know we have at most 1 writer on each participant -->
            <total_writers>
                <initial>1</initial>
                <maximum>1</maximum>
                <increment>0</increment>
            </total_writers>
            <max_partitions>256</max_partitions>
            <max_user_data>256</max_user_data>
            <max_properties>512</max_properties>

            <!-- content_filter cannot be configured using XML (yet) -->
        </allocation>
    </rtps>
</participant>
3.1.2.2.7. PropertyPolicyQos

This additional QoS Policy (PropertyPolicyQos) stores name/value pairs that can be used to configure certain DDS settings that cannot be configured directly using an standard QoS Policy. For the complete list of settings that can be configured with this QoS Policy, please refer to PropertyPolicyQos Options.

This QoS also allows to add custom user properties that could be sent to the external entities. This could be done by setting as true the propagate value of the Property.

Note

This QoS Policy applies to DomainParticipant, DataWriter and DataReader entities.
It cannot be changed on enabled entities.

Example
// This example uses a DataWriter, but it can also be applied to DomainParticipant and DataReader entities
DataWriterQos writer_qos;
// Add new property for the Auth:PKI-DH plugin
writer_qos.properties().properties().emplace_back("dds.sec.auth.plugin", "builtin.PKI-DH");
// Add new property for the Access:Permissions plugin
writer_qos.properties().properties().emplace_back(eprosima::fastdds::rtps::Property("dds.sec.access.plugin",
        "builtin.Access-Permissions"));

// Add new user custom property to send to external Participants
writer_qos.properties().properties().emplace_back("Custom Property Name", "Custom value", true);
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<participant profile_name="secure_participant_conf_all_plugin_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Activate Auth:PKI-DH plugin -->
                <property>
                    <name>dds.sec.auth.plugin</name>
                    <value>builtin.PKI-DH</value>
                </property>

                <!-- Activate Access:Permissions plugin -->
                <property>
                    <name>dds.sec.access.plugin</name>
                    <value>builtin.Access-Permissions</value>
                </property>

                <!-- User Custom Property to send externally -->
                <property>
                    <name>Custom Property Name</name>
                    <value>Custom value</value>
                    <propagate>true</propagate>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>
3.1.2.2.8. PublishModeQosPolicy

This QoS Policy configures how the DataWriter sends the data. See PublishModeQosPolicy.

It also configures the name of the flow controller to use when asynchronous publishing is used. It should be the name of a flow controller registered on the creation of the DomainParticipant. See FlowControllersQos.

List of QoS Policy data members:

Note

This QoS Policy applies to DataWriter entities.
It cannot be changed on enabled entities.

PublishModeQosPolicyKind

There are two possible values (see PublishModeQosPolicyKind):

  • SYNCHRONOUS_PUBLISH_MODE: The data is sent in the context of the user thread that calls the write operation.

  • ASYNCHRONOUS_PUBLISH_MODE: An internal thread takes the responsibility of sending the data asynchronously. The write operation returns before the data is actually sent.

Also, the flow_controller_name has to be set to the name of a valid Flow Controllers descriptor name.

Example
// This example only applies to DataWriter entities
DataWriterQos writer_qos;
// The PublishModeQosPolicy is constructed with kind = SYNCHRONOUS by default
// Change the kind to ASYNCHRONOUS
writer_qos.publish_mode().kind = ASYNCHRONOUS_PUBLISH_MODE;
// Use modified QoS in the creation of the DataWriter entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_profile_qos_publishmode">
    <qos>
        <publishMode>
            <kind>ASYNCHRONOUS</kind>
            <flow_controller_name>example_flow_controller</flow_controller_name>
        </publishMode>
    </qos>
</data_writer>
3.1.2.2.9. ReaderResourceLimitsQos

This QoS Policy states the limits for the matched DataWriters’ resource limited collections based on the maximum number of DataWriters that are going to match with the DataReader. See ReaderResourceLimitsQos.

List of QoS Policy data members:

Note

This QoS Policy applies to DataReader entities.
It cannot be changed on enabled entities.

Example
// This example only applies to DataReader entities
DataReaderQos reader_qos;
// Set the maximum size for writer matched resource limits collection to 1 and its allocation configuration to fixed size
reader_qos.reader_resource_limits().matched_publisher_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(1u);
// Set the maximum size for sample info resource limits to 22 and its allocation configuration to fixed size
reader_qos.reader_resource_limits().sample_infos_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(22u);
// Set the maximum size for writer matched resource limits collection to 3 and its allocation configuration to fixed size
reader_qos.reader_resource_limits().outstanding_reads_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(3u);
reader_qos.reader_resource_limits().max_samples_per_read = 42;
// Use modified QoS in the creation of the DataReader entity
reader_ = subscriber_->create_datareader(topic_, reader_qos);
<data_reader profile_name="alloc_qos_example_sub">
    <!-- we know we will only have one matching publisher -->
    <matchedPublishersAllocation>
        <initial>1</initial>
        <maximum>1</maximum>
        <increment>0</increment>
    </matchedPublishersAllocation>
</data_reader>
3.1.2.2.10. WriterResourceLimitsQos

This QoS Policy states the limits for the matched DataReaders’ resource limited collections based on the maximum number of DataReaders that are going to match with the DataWriter. See WriterResourceLimitsQos.

List of QoS Policy data members:

Note

This QoS Policy applies to DataWriter entities.
It cannot be changed on enabled entities.

Example
// This example only applies to DataWriter entities
DataWriterQos writer_qos;
// Set the maximum size for reader matched resource limits collection to 3 and its allocation configuration to fixed size
writer_qos.writer_resource_limits().matched_subscriber_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(3u);
// Set the maximum number of writer side content filters to 1 and its allocation configuration to fixed size
writer_qos.writer_resource_limits().reader_filters_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(1u);
// Use modified QoS in the creation of the DataWriter entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="alloc_qos_example_pub_for_topic_1">
    <!-- we know we will have three matching subscribers -->
    <matchedSubscribersAllocation>
        <initial>3</initial>
        <maximum>3</maximum>
        <increment>0</increment>
    </matchedSubscribersAllocation>

    <!-- reader_filters_allocation cannot be configured using XML (yet) -->
</data_writer>
3.1.2.2.11. RTPSEndpointQos

This QoS Policy configures the aspects of an RTPS endpoint, such as the list of locators, the identifiers, and the history memory policy. See RTPSEndpointQos.

List of QoS Policy data members:

  • unicast_locator_list: Defines the list of unicast locators associated to the DDS Entity. DataReaders and DataWriters inherit the list of unicast locators set in the DomainParticipant, but it can be changed by means of this QoS.

  • multicast_locator_list: Stores the list of multicast locators associated to the DDS Entity. By default, DataReaders and DataWriters do not use any multicast locator, but it can be changed by means of this QoS.

  • remote_locator_list: States the list of remote locators associated to the DDS Entity.

  • external_unicast_locators: Defines the External Locators to announce for the communication with this DDS Entity.

  • ignore_non_matching_locators: Defines whether to ignore locators received on announcements from other DDS entities when they don’t match with any of the locators announced by this DDS Entity.

  • user_defined_id: Establishes the unique identifier used for StaticEndpointDiscovery.

  • entity_id: The user can specify the identifier for the endpoint.

  • history_memory_policy: Indicates the way the memory is managed in terms of dealing with the CacheChanges.

Note

This QoS Policy applies to DataWriter and DataReader entities.
It cannot be changed on enabled entities.

MemoryManagementPolicy

There are four possible values (see MemoryManagementPolicy):

  • PREALLOCATED_MEMORY_MODE: This option sets the size to the maximum of each data type. It produces the largest memory footprint but the smallest allocation count.

  • PREALLOCATED_WITH_REALLOC_MEMORY_MODE: This option set the size to the default for each data type and it requires reallocation when a bigger message arrives. It produces a lower memory footprint at the expense of increasing the allocation count.

  • DYNAMIC_RESERVE_MEMORY_MODE: This option allocates the size dynamically at the time of message arrival. It produces the least memory footprint but the highest allocation count.

  • DYNAMIC_REUSABLE_MEMORY_MODE: This option is similar to DYNAMIC_RESERVE_MEMORY_MODE, but the allocated memory is reused for future messages.

Example
// This example uses a DataWriter, but it can also be applied to DataReader entities
DataWriterQos writer_qos;
// Add new unicast locator with port 7800
eprosima::fastdds::rtps::Locator_t new_unicast_locator;
new_unicast_locator.port = 7800;
writer_qos.endpoint().unicast_locator_list.push_back(new_unicast_locator);
// Add new multicast locator with IP 239.255.0.4 and port 7900
eprosima::fastdds::rtps::Locator_t new_multicast_locator;
eprosima::fastdds::rtps::IPLocator::setIPv4(new_multicast_locator, "239.255.0.4");
new_multicast_locator.port = 7900;
writer_qos.endpoint().multicast_locator_list.push_back(new_multicast_locator);
// Add an external locator with IP 100.100.100.10, port 12345, mask 24, externality 1, and cost 0
eprosima::fastdds::rtps::LocatorWithMask external_locator;
external_locator.kind = LOCATOR_KIND_UDPv4;
external_locator.port = 12345;
external_locator.mask(24);
writer_qos.endpoint().external_unicast_locators[1][0].push_back(external_locator);
// Drop non matching locators
writer_qos.endpoint().ignore_non_matching_locators = true;
// Set 3 as user defined id
writer_qos.endpoint().user_defined_id = 3;
// Set 4 as entity id
writer_qos.endpoint().entity_id = 4;
// The RTPSWriterQos is constructed with history_memory_policy = PREALLOCATED by default
// Change the history_memory_policy to DYNAMIC_RESERVE
writer_qos.endpoint().history_memory_policy = eprosima::fastdds::rtps::DYNAMIC_RESERVE_MEMORY_MODE;
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
<data_writer profile_name="writer_xml_conf_unicast_locators_profile">
    <userDefinedID>3</userDefinedID>
    <entityID>2</entityID> <!-- Int16 -->
    <unicastLocatorList>
        <locator>
            <udpv4>
                <port>7800</port>
            </udpv4>
        </locator>
    </unicastLocatorList>
    <multicastLocatorList>
        <locator>
            <udpv4>
                <address>239.255.0.4</address>
                <port>7900</port>
            </udpv4>
        </locator>
    </multicastLocatorList>
    <external_unicast_locators>
        <udpv4 externality="1" cost="0" mask="24">
            <address>100.100.100.10</address>
            <port>12345</port>
        </udpv4>
    </external_unicast_locators>
    <ignore_non_matching_locators>true</ignore_non_matching_locators>
    <!-- The history memory policy is changed to DYNAMIC_RESERVE -->
    <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
</data_writer>

<data_reader profile_name="reader_xml_conf_unicast_locators_profile">
    <userDefinedID>5</userDefinedID>
    <entityID>4</entityID> <!-- Int16 -->
    <unicastLocatorList>
        <locator>
            <udpv4>
                <port>7800</port>
            </udpv4>
        </locator>
    </unicastLocatorList>
    <multicastLocatorList>
        <locator>
            <udpv4>
                <address>239.255.0.4</address>
                <port>7900</port>
            </udpv4>
        </locator>
    </multicastLocatorList>
    <external_unicast_locators>
        <udpv4 externality="1" cost="0" mask="24">
            <address>100.100.100.10</address>
            <port>12345</port>
        </udpv4>
    </external_unicast_locators>
    <ignore_non_matching_locators>true</ignore_non_matching_locators>
    <historyMemoryPolicy>PREALLOCATED_WITH_REALLOC</historyMemoryPolicy>
</data_reader>
3.1.2.2.12. ThreadSettings

This structure is part of other QoS policies, and allows controlling some OS settings for the threads created. The default values will leave the default OS settings on the created threads. Changing these values may require special permissions.

Data Member Name

Type

Default Value

scheduling_policy

int32_t

-1

priority

int32_t

-2^31

affinity

uint32_t

0

stack_size

int32_t

-1

  • scheduling_policy: Configures the scheduling policy used for the thread. This value is platform specific and it is used as-is to configure the specific platform thread. It is ignored on Windows platforms.

  • priority: Configures the thread’s priority. This value is platform specific and it is used as-is to configure the specific platform thread.

  • affinity: On some systems (Windows, Linux), this is a bit mask for setting the threads affinity to each core individually. On MacOS, this sets the affinity tag for the thread, and the OS tries to share the L2 cache between threads with the same affinity. This value is platform specific and it is used as-is to configure the specific platform thread.

  • stack_size: Configures the thread’s stack size in bytes. This value is platform specific and it is used as-is to configure the specific platform thread.

The ThreadSettings for reception threads in port-based transport descriptors can also be configured by associating each thread-specific configuration with its corresponding port number.

Example

The following example illustrate a thread settings configuration:

// This example uses a specific thread of the DomainParticipantQos, but it can also be applied to most of
// the threads used by FastDDS in DomainParticipantFactoryQos, DomainParticipantQos or DataSharingQosPolicy.
// Each thread has its own getter and setter function. See Fast DDS documentation for further details.
DomainParticipantQos participant_qos;
participant_qos.timed_events_thread().scheduling_policy = 2;
participant_qos.timed_events_thread().priority = 10;
participant_qos.timed_events_thread().affinity = 4;
participant_qos.timed_events_thread().stack_size = 2000;

// Use modified QoS in the creation of the corresponding entity
participant_ = factory_->create_participant(domain, participant_qos);
<thread_settings>
    <scheduling_policy>2</scheduling_policy>
    <priority>10</priority>
    <affinity>4</affinity>
    <stack_size>2000</stack_size>
</thread_settings>

The subsequent example depicts a reception threads settings configuration:

// Implement a Custom class, derived from PortBasedTransportDescriptor, to set the reception threads configuration
CustomPortBasedTransportDescriptor descriptor;
PortBasedTransportDescriptor::ReceptionThreadsConfigMap reception_threads_config;
reception_threads_config[20000].scheduling_policy = 1;
reception_threads_config[20000].priority = 30;
reception_threads_config[20000].affinity = 2;
reception_threads_config[20000].stack_size = 1024;
reception_threads_config[20001].scheduling_policy = 2;
reception_threads_config[20001].priority = 10;
reception_threads_config[20001].affinity = 6;
reception_threads_config[20001].stack_size = 4096;

// Use setter to set the reception threads configuration
descriptor.reception_threads(reception_threads_config);
<transport_descriptors>
    <transport_descriptor>
        <transport_id>test_transport</transport_id>
        <type>UDPv4</type>
        <reception_threads>
            <reception_thread port="20000">
                <scheduling_policy>1</scheduling_policy>
                <priority>30</priority>
                <affinity>2</affinity>
                <stack_size>1024</stack_size>
            </reception_thread>
            <reception_thread port="20001">
                <scheduling_policy>2</scheduling_policy>
                <priority>10</priority>
                <affinity>6</affinity>
                <stack_size>4096</stack_size>
            </reception_thread>
        </reception_threads>
    </transport_descriptor>
</transport_descriptors>
3.1.2.2.13. TransportConfigQos

This QoS Policy allows the configuration of the transport layer settings. See TransportConfigQos.

List of QoS Policy data members:

Data Member Name

Type

Default Value

user_transports

std::vector<std::shared_ptr<TransportDescriptorInterface>>

Empty vector

use_builtin_transports

bool

true

send_socket_buffer_size

uint32_t

0

listen_socket_buffer_size

uint32_t

0

builtin_transports_reception_threads()

ThreadSettings

max_msg_size_no_frag

uint32_t

0

netmask_filter

fastdds::rtps::NetmaskFilterKind

AUTO

  • user_transports: This data member defines the list of transports to use alongside or in place of builtins.

  • use_builtin_transports: It controls whether the built-in transport layer is enabled or disabled. If it is set to false, the default UDPv4 implementation is disabled.

  • send_socket_buffer_size: By default, Fast DDS creates socket buffers using the system default size. This data member allows to change the send socket buffer size used to send data.

  • listen_socket_buffer_size: The listen socket buffer size is also created with the system default size, but it can be changed using this data member.

  • builtin_transports_reception_threads(): The ThreadSettings for the reception threads of the builtin transports.

  • max_msg_size_no_frag: Maximum message size used to avoid fragmentation. Useful when the configured transports allow for big datagrams to be sent (i.e. SHM or TCP).

  • netmask_filter: Network filter configuration.

Note

This QoS Policy applies to DomainParticipant entities.
It cannot be changed on enabled entities.

TransportDescriptorInterface

This structure is the base for the data type used to define transport configuration.

List of structure members:

Member Name

Type

maxMessageSize

uint32_t

maxInitialPeersRange

uint32_t

  • maxMessageSize: This member sets the maximum size in bytes of the transport’s message buffer.

  • maxInitialPeersRange: This member states the maximum number of guessed initial peers to try to connect.

Example
// This example only applies to DomainParticipant entities
DomainParticipantQos participant_qos;
// Add new transport to the list of user transports
std::shared_ptr<eprosima::fastdds::rtps::UDPv4TransportDescriptor> descriptor =
        std::make_shared<eprosima::fastdds::rtps::UDPv4TransportDescriptor>();
descriptor->sendBufferSize = 9126;
descriptor->receiveBufferSize = 9126;
participant_qos.transport().user_transports.push_back(descriptor);
// Set use_builtin_transports to false
participant_qos.transport().use_builtin_transports = false;
// [OPTIONAL] Set ThreadSettings for the builtin transports reception threads
participant_qos.transport().builtin_transports_reception_threads_ =
        eprosima::fastdds::rtps::ThreadSettings{2, 2, 2, 2};
// Set max_msg_size_no_frag to a value > 65500 KB
participant_qos.transport().max_msg_size_no_frag = 70000;
// Configure netmask filter
participant_qos.transport().netmask_filter = eprosima::fastdds::rtps::NetmaskFilterKind::ON;
// Use modified QoS in the creation of the DomainParticipant entity
participant_ = factory_->create_participant(domain, participant_qos);
<transport_descriptors>
    <transport_descriptor>
        <transport_id>my_transport</transport_id>
        <type>UDPv4</type>
        <sendBufferSize>9216</sendBufferSize>
        <receiveBufferSize>9216</receiveBufferSize>
    </transport_descriptor>
</transport_descriptors>

<participant profile_name="my_transport">
    <rtps>
        <userTransports>
            <transport_id>my_transport</transport_id>
        </userTransports>
        <useBuiltinTransports>false</useBuiltinTransports>
        <netmask_filter>ON</netmask_filter>
    </rtps>
</participant>

Note

TransportConfigQos can also be configured modifying the builtin transports configuration by selecting one of the available builtin transports options. See Managing the Builtin Transports or setup_transports().

3.1.2.2.14. WireProtocolConfigQos

This QoS Policy allows the configuration of the wire protocol.

List of QoS Policy data members:

List of QoS Policy methods:

Method name

Input parameters

Return type

Description

easy_mode()

std::string ip

ReturnCode_t

Setter for easy_mode_ip_ private member.

easy_mode()

Empty

std::string

Getter for easy_mode_ip_ private member.

  • prefix: This data member allows the user to set manually the GUID prefix.

  • participant_id: It sets the participant identifier. By default, it will be automatically generated by the Domain.

  • builtin: This data member allows the configuration of the built-in parameters.

  • port: This data member allows the configuration of the port parameters and gains related to the RTPS protocol (Well Known Ports).

  • default_unicast_locator_list: States the default list of unicast locators to be used for any endpoint defined inside the RTPSParticipant in the case that it was defined without unicast locators. This list should include at least one locator.

  • default_multicast_locator_list: Stores the default list of multicast locators to be used for any endpoint defined inside the RTPSParticipant in the case that it was defined without multicast locators. This list is usually left empty.

  • default_external_unicast_locators: Defines the External Locators to be used for any endpoint defined inside the participant in the case that it was defined without unicast locators.

  • ignore_non_matching_locators: Defines whether to ignore locators received on announcements from other DDS participants when they don’t match with any of the locators announced by this DDS participant.

  • easy_mode(): This method allows the user to set or get the easy_mode_ip_ private member, which stores the IP address to be used in the Discovery Server Easy Mode configuration. When easy_mode() setter is called, the input string parameter is validated to make sure it is a valid IPv4 address. If not, easy_mode_ip_ will be set to an empty string, indicating that ROS 2 Easy Mode is disabled.

Note

If the Easy Mode Discovery Server IP is configured simultaneously using the ROS2_EASY_MODE environment variable and manually via XML or with WireProtocolConfigQos, the manually configured value takes precedence, thereby ignoring the environment variable value.

Note

This QoS Policy applies to DomainParticipant entities.

Important

The only mutable field on enabled entities is m_DiscoveryServers, which is contained in discovery_config within builtin (see Modifying remote servers list at run time).

Note

Deployments where multiple DomainParticipants are created within the same host can lead into denying available ports for them if the amount of DomainParticipants created reaches the value of BuiltinAttributes::mutation_tries (100 by default). When that happens, the DomainParticipants will not be able to create the listening ports (this is notified with a log warning) and will be created without unicast locators configured.

Example
// This example only applies to DomainParticipant entities
DomainParticipantQos participant_qos;
// Set the guid prefix
std::istringstream("72.61.73.70.66.61.72.6d.74.65.73.74") >> participant_qos.wire_protocol().prefix;
// Manually set the participantId
participant_qos.wire_protocol().participant_id = 11;
// Configure Builtin Attributes
participant_qos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        eprosima::fastdds::rtps::DiscoveryProtocol::SERVER;
// Add locator to unicast list
eprosima::fastdds::rtps::Locator_t server_locator;
eprosima::fastdds::rtps::IPLocator::setIPv4(server_locator, "192.168.10.57");
server_locator.port = 56542;
participant_qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(server_locator);
// Add a metatraffic external locator with IP 100.100.100.10, port 34567, mask 24, externality 1, and cost 0
eprosima::fastdds::rtps::LocatorWithMask meta_external_locator;
meta_external_locator.kind = LOCATOR_KIND_UDPv4;
meta_external_locator.port = 34567;
meta_external_locator.mask(24);
participant_qos.wire_protocol().builtin.metatraffic_external_unicast_locators[1][0].push_back(
    meta_external_locator);
// Add locator to default unicast locator list
eprosima::fastdds::rtps::Locator_t unicast_locator;
eprosima::fastdds::rtps::IPLocator::setIPv4(unicast_locator, 192, 168, 1, 41);
unicast_locator.port = 7400;
participant_qos.wire_protocol().default_unicast_locator_list.push_back(unicast_locator);
// Add locator to default multicast locator list
eprosima::fastdds::rtps::Locator_t multicast_locator;
eprosima::fastdds::rtps::IPLocator::setIPv4(multicast_locator, 192, 168, 1, 41);
multicast_locator.port = 7400;
participant_qos.wire_protocol().default_multicast_locator_list.push_back(multicast_locator);
// Add a default external locator with IP 100.100.100.10, port 23456, mask 24, externality 1, and cost 0
eprosima::fastdds::rtps::LocatorWithMask external_locator;
external_locator.kind = LOCATOR_KIND_UDPv4;
external_locator.port = 23456;
external_locator.mask(24);
participant_qos.wire_protocol().default_external_unicast_locators[1][0].push_back(external_locator);
// Drop non matching locators
participant_qos.wire_protocol().ignore_non_matching_locators = true;
// Configure the ROS 2 Easy Mode master Discovery Server IP
participant_qos.wire_protocol().easy_mode("127.0.0.1");
// Increase mutation tries
participant_qos.wire_protocol().builtin.mutation_tries = 300u;
// Use a specific flow controller to control the builtin writers
participant_qos.wire_protocol().builtin.flow_controller_name = "AlreadyExistingFlowController";
// Use modified QoS in the creation of the DomainParticipant entity
participant_ = factory_->create_participant(domain, participant_qos);
<participant profile_name="UDP SERVER WP" is_default_profile="true">
    <rtps>
        <prefix>72.61.73.70.66.61.72.6d.74.65.73.74</prefix>
        <participantID>11</participantID>
        <easy_mode_ip>127.0.0.1</easy_mode_ip>
        <builtin>
            <discovery_config>
                <discoveryProtocol>SERVER</discoveryProtocol>
            </discovery_config>
            <metatrafficUnicastLocatorList>
                <locator>
                    <udpv4>
                        <address>192.168.10.57</address>
                        <port>56542</port>
                    </udpv4>
                </locator>
            </metatrafficUnicastLocatorList>
            <metatraffic_external_unicast_locators>
                <udpv4 externality="1" cost="0" mask="24">
                    <address>100.100.100.10</address>
                    <port>34567</port>
                </udpv4>
            </metatraffic_external_unicast_locators>
            <mutation_tries>300</mutation_tries>
        </builtin>
        <defaultUnicastLocatorList>
            <locator>
                <udpv4>
                    <!-- Access as physical, like UDP -->
                    <port>7400</port>
                    <address>192.168.1.41</address>
                </udpv4>
            </locator>
        </defaultUnicastLocatorList>

        <defaultMulticastLocatorList>
            <locator>
                <udpv4>
                    <!-- Access as physical, like UDP -->
                    <port>7400</port>
                    <address>192.168.1.41</address>
                </udpv4>
            </locator>
        </defaultMulticastLocatorList>

        <default_external_unicast_locators>
            <udpv4 externality="1" cost="0" mask="24">
                <address>100.100.100.10</address>
                <port>23456</port>
            </udpv4>
        </default_external_unicast_locators>

        <ignore_non_matching_locators>true</ignore_non_matching_locators>
    </rtps>
</participant>

Note

For extended XML information, refer to DomainParticipant configuration and Builtin parameters XML sections.

3.1.2.3. XTypes Extensions

This section explain those QoS Policy extensions defined in the XTypes Specification:

3.1.2.3.1. DataRepresentationQosPolicy

This XTypes QoS Policy states which data representations will be used by the DataWriters and DataReaders.

The DataWriters offer a single data representation that will be used to communicate with the matched DataReaders. The DataReaders can request one or more data representations and in order to have communication with the DataWriter, the offered data representation needs to be contained within the DataReader request. See DataRepresentationQosPolicy.

List of QoS Policy data members:

Data Member Name

Type

Default Value

DataReader default value

DataWriter default value

Topic default value

m_value

std::vector<DataRepresentationId>

Empty vector

[XCDR_DATA_REPRESENTATION,
XCDR2_DATA_REPRESENTATION]

[XCDR2_DATA_REPRESENTATION]

[XCDR_DATA_REPRESENTATION]

Note

This QoS Policy applies to Topic, DataReader and DataWriter entities.
It cannot be changed on enabled entities.

DataRepresentationId

There are three possible values (see DataRepresentationId):

Example
C++
// This example uses a DataWriter, but it can also be applied to Topic entities.
// DataRepresentationQosPolicy of DataReaders is contained in the TypeConsistencyQos
// (for further details see TypeConsistencyQos section).
DataWriterQos writer_qos;
// Add XCDR v1 data representation to the list of valid representations
writer_qos.representation().m_value.push_back(DataRepresentationId_t::XCDR_DATA_REPRESENTATION);
// Add XML data representation to the list of valid representations
writer_qos.representation().m_value.push_back(DataRepresentationId_t::XML_DATA_REPRESENTATION);
// Use modified QoS in the creation of the corresponding entity
writer_ = publisher_->create_datawriter(topic_, writer_qos);
XML

This QoS Policy cannot be configured using XML for the moment.

3.1.2.3.2. TypeConsistencyEnforcementQosPolicy

Warning

This QoS Policy will be implemented in future releases.

This XTypes QoS Policy extension defines the rules for determining whether the data type used in the DataWriter is consistent with the one used in the DataReader. See TypeConsistencyEnforcementQosPolicy.

List of QoS Policy data members:

  • m_kind: It determines whether the type in the DataWriter type must be equal to the type in the DataReader or not. See TypeConsistencyKind for further details.

  • m_ignore_sequence_bounds: This data member controls whether the sequence bounds are taken into account for type assignability or not. If its value is true, the sequences maximum lengths are not considered, which means that a sequence T2 with length L2 would be assignable to a sequence T1 with length L1, even if L2 is greater than L1. But if it is false, L1 must be higher or equal to L2 to consider the sequences as assignable.

  • m_ignore_string_bounds: It controls whether the string bounds are considered for type assignation or not. If its value is true, the strings maximum lengths are not considered, which means that a string S2 with length L2 would be assignable to a string S1 with length L1, even if L2 is greater than L1. But if it is false, L1 must be higher or equal to L2 to consider the strings as assignable.

  • m_ignore_member_names: This boolean controls whether the member names are taken into consideration for type assignability or not. If it is true, apart from the member ID, the member names are considered as part of assignability, which means that the members with the same ID must also have the same name. But if the value is false, the member names are ignored.

  • m_prevent_type_widening: This data member controls whether the type widening is allowed or not. If it is false, the type widening is permitted, but if true, a wider type cannot be assignable to a narrower type.

  • m_force_type_validation: It controls if the service needs the type information to complete the matching between a DataWriter and a DataReader. If it is enabled, it must have the Complete Type Information, otherwise it is not necessary.

Note

This QoS Policy applies to DataReader entities.
It cannot be changed on enabled entities.

TypeConsistencyKind

There are two possible values:

  • DISALLOW_TYPE_COERCION: The DataWriter and the DataReader must support the same data type in order to communicate.

  • ALLOW_TYPE_COERCION: The DataWriter and the DataReader do not need to support the same data type in order to communicate as long as the DataReader’s type is assignable from the DataWriter’s type.

3.1.3. Status

Each Entity is associated with a set of Status objects whose values represent the communication status of that Entity. Changes on the status values occur due to communication events related to each of the entities, e.g., when new data arrives, a new participant is discovered, or a remote endpoint is lost. The status is decomposed into several status objects, each concerning a different aspect of the communication, so that each of these status objects can vary independently of the others.

Changes on a status object trigger the corresponding Listener callbacks that allow the Entity to inform the application about the event. For a given status object with name fooStatus, the entity listener interface defines a callback function on_foo() that will be called when the status changes. Beware that some statuses have data members that are reset every time the corresponding listener is called. The only exception to this rule is when the entity has no listener attached, so the callback cannot be called. See the documentation of each status for details.

Conditions and Wait-sets provide the application with an alternative mechanism to make it aware of changes on status objects, by means of a StatusCondition. The advantage of this mechanism is that the application can wait for changes on several entities at the same time. It will also help the determinism of your system, as the notification is not processed on an internal thread, as it is done when using listeners.

The entities expose functions to access the value of its statuses. For a given status with name fooStatus, the entity exposes a member function get_foo() to access the data in its fooStatus. The only exceptions are DataOnReaders and DataAvailable. These getter functions return a read-only struct where all data members are public and accessible to the application. Beware that some statuses have data members that are reset every time the getter function is called by the application. See the documentation of each status for details.

The following subsections describe each of the status objects, their data members, and to which Entity type they concern. The next table offers a quick reference as well as the corresponding bit for each status in the StatusMask.

3.1.3.1. InconsistentTopicStatus

This status changes every time an inconsistent remote Topic is discovered, that is, one with the same name but different characteristics than the current Topic. See InconsistentTopicStatus.

List of status data members:

Data Member Name

Type

total_count

int32_t

total_count_change

int32_t

Warning

Currently this status is not supported and will be implemented in future releases. As a result, trying to access this status will return NOT_SUPPORTED and the corresponding listener will never be called.

3.1.3.2. DataOnReaders

This status becomes active every time there is new data available for the application on any DataReader belonging to the current Subscriber. There is no getter function to access this status, as it does not keep track of any information related to the data itself. Its only purpose is to trigger the on_data_on_readers() callback on the listener attached to the DataReader.

3.1.3.3. DataAvailable

This status becomes active every time there is new data available for the application on the DataReader. There is no getter function to access this status, as it does not keep track of any information related to the data itself. Its only purpose is to trigger the on_data_available() callback on the listener attached to the DataReader.

3.1.3.4. LivelinessChangedStatus

This status changes every time the liveliness status of a matched DataWriter has changed. Either because a DataWriter that was inactive has become active or the other way around. See LivelinessChangedStatus.

List of status data members:

  • alive_count: Total number of currently active DataWriters. This count increases every time a newly matched DataWriter asserts its liveliness or a DataWriter that was considered not alive reasserts its liveliness. It decreases every time an active DataWriter becomes not alive, either because it failed to asserts its liveliness or because it was deleted for any reason.

  • not_alive_count: Total number of matched DataWriters that are currently considered not alive. This count increases every time an active DataWriter becomes not alive because it fails to assert its liveliness. It decreases every time a DataWriter that was considered not alive reasserts its liveliness. Normal matching and unmatching of DataWriters does not affect this count.

  • alive_count_change: The change in alive_count since the last time on_liveliness_changed() was called or the status was read. It can have positive or negative values.

  • not_alive_count_change: The change in not_alive_count since the last time on_liveliness_changed() was called or the status was read. It can have positive or negative values.

  • last_publication_handle: Handle to the last DataWriter whose liveliness status was changed. If no liveliness has ever changed, it will have value c_InstanceHandle_Unknown.

3.1.3.5. RequestedDeadlineMissedStatus

This status changes every time the DataReader does not receive data within the deadline period configured on its DataReaderQos. See RequestedDeadlineMissedStatus.

List of status data members:

  • total_count: Total cumulative count of missed deadlines for any instance read by the current DataReader. As the deadline period applies to each instance of the Topic independently, the count will will be incremented by one for each instance for which data was not received in the deadline period.

  • total_count_change: The change in total_count since the last time on_requested_deadline_missed() was called or the status was read. It can only have zero or positive values.

  • last_instance_handle: Handle to the last instance that missed the deadline. If no deadline was ever missed, it will have value c_InstanceHandle_Unknown.

3.1.3.6. RequestedIncompatibleQosStatus

This status changes every time the DataReader finds a DataWriter that matches the Topic and has a common partition, but with a QoS configuration incompatible with the one defined on the DataReader. See RequestedIncompatibleQosStatus.

List of status data members:

  • total_count: Total cumulative count of DataWriters found matching the Topic and with a common partition, but with a QoS configuration that is incompatible with the one defined on the DataReader.

  • total_count_change: The change in total_count since the last time on_requested_incompatible_qos() was called or the status was read. It can only have zero or positive values.

  • last_policy_id: The policy ID of one of the policies that was found to be incompatible with the current DataReader. If more than one policy happens to be incompatible, only one of them will be reported in this member.

  • policies: A collection that holds, for each policy, the total number of times that the policy was found to be incompatible with the one offered by a remote DataWriter that matched the Topic and with a common partition. See QosPolicyCountSeq and QosPolicyCount for more information the information that is stored for each policy.

3.1.3.6.1. QosPolicyCountSeq

Holds a QosPolicyCount for each Policy, indexed by its QosPolicyId_t. Therefore, the Qos Policy with ID N will be at position N in the sequence. See QosPolicyCountSeq.

DataReader* reader_ =
        subscriber_->create_datareader(topic_, DATAREADER_QOS_DEFAULT);

// Get how many times ReliabilityQosPolicy was not compatible with a remote writer
RequestedIncompatibleQosStatus status;
reader_->get_requested_incompatible_qos_status(status);
uint32_t incompatible_reliability_count = status.policies[RELIABILITY_QOS_POLICY_ID].count;
3.1.3.6.2. QosPolicyCount

This structure holds a counter for a policy. See QosPolicyCount.

List of data members:

Data Member Name

Type

policy_id

QosPolicyId_t

count

int32_t

  • policy_id: The ID of the policy.

  • count: The counter value for the policy.

3.1.3.7. SampleLostStatus

This status changes every time a new data sample is lost and will never be received. See SampleLostStatus.

There are two different criteria for considering a sample as lost depending on the reliability():

  • When using BEST_EFFORT_RELIABILITY_QOS, a not yet received sample is considered lost whenever a sample with a greater sequence number is received.

  • When using RELIABLE_RELIABILITY_QOS, a not yet received sample is considered lost whenever the DataWriter informs, through an RTPS HEARTBEAT submessage, that the sample is not available anymore.

List of status data members:

Data Member Name

Type

total_count

int32_t

total_count_change

int32_t

3.1.3.8. SampleRejectedStatus

This status changes every time an incoming data sample is rejected by the DataReader. The reason for the rejection is defined by SampleRejectedStatusKind. For further information see SampleRejectedStatus.

List of status data members:

3.1.3.8.1. SampleRejectedStatusKind

In Fast DDS, samples can be rejected due to resource limit reasons. However, the fact that the samples are rejected does not imply that they are lost, i.e. a rejected sample may be accepted in the future.

SampleRejectedStatusKind specifies the reason of the rejection:

  • NOT_REJECTED specifies that the samples were not rejected.

  • REJECTED_BY_SAMPLES_LIMIT specifies that the samples were rejected because there were not enough resources to stored them. This can happen even when there are free resources if those resources must be guaranteed to be available for other samples. This situation, which arises in the RTPS layer, occurs when there are yet to be received samples with lower sequence number and there is not enough resources for all of them (because max_samples has been reached).

  • REJECTED_BY_INSTANCES_LIMIT specifies that the samples were rejected because there were not enough resources to allocate the samples’ instances. This situation, which arises in the DDS layer, more precisely in the in the DataReader’s history, occurs when the sample corresponds to a new instance for which the middleware should reserve resources but the history’s number of instances has already reached max_instances.

  • REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT specifies that the samples were rejected because there were not enough resources within their instance to stored them. This situation, which arises in the DDS layer, more precisely in the DataReader’s history, occurs when the DataReader is configured with KEEP_ALL_HISTORY_QOS and the instance’s number of samples has reached max_samples_per_instance.

3.1.3.9. SubscriptionMatchedStatus

This status changes every time the DataReader finds a DataWriter that matches the Topic and has a common partition and a compatible QoS, or has ceased to be matched with a DataWriter that was previously considered to be matched. See SubscriptionMatchedStatus.

List of status data members:

3.1.3.10. LivelinessLostStatus

This status changes every time the DataWriter failed to assert its liveliness during the period configured on its DataWriterQos. This means that matched DataReader entities will consider the DataWriter as no longer alive. See LivelinessLostStatus.

List of status data members:

Data Member Name

Type

total_count

int32_t

total_count_change

int32_t

  • total_count: Total cumulative count of times that the DataWriter failed to assert its liveliness during the period configured on its DataWriterQos, becoming considered not alive. This count does not change when the DataWriter is already considered not alive and simply remains not alive for another liveliness period.

  • total_count_change: The change in total_count since the last time on_liveliness_lost() was called or the status was read. It can only have zero or positive values.

3.1.3.11. OfferedDeadlineMissedStatus

This status changes every time the DataWriter fails to provide data within the deadline period configured on its DataWriterQos. See OfferedDeadlineMissedStatus.

List of status data members:

  • total_count: Total cumulative count of missed deadlines for any instance written by the current DataWriter. As the deadline period applies to each instance of the Topic independently, the count will will be incremented by one for each instance for which data was not sent in the deadline period.

  • total_count_change: The change in total_count since the last time on_offered_deadline_missed() was called or the status was read. It can only have zero or positive values.

  • last_instance_handle: Handle to the last instance that missed the deadline. If no deadline was ever missed, it will have value c_InstanceHandle_Unknown.

3.1.3.12. OfferedIncompatibleQosStatus

This status changes every time the DataWriter finds a DataReader that matches the Topic and has a common partition, but with a QoS configuration that is incompatible with the one defined on the DataWriter. See OfferedIncompatibleQosStatus.

List of status data members:

  • total_count: Total cumulative count of DataReaders found matching the Topic and with a common partition, but with a QoS configuration that is incompatible with the one defined on the DataWriter.

  • total_count_change: The change in total_count since the last time on_offered_incompatible_qos() was called or the status was read. It can only have zero or positive values.

  • last_policy_id: The policy ID of one of the policies that was found to be incompatible with the current DataWriter. If more than one policy happens to be incompatible, only one of them will be reported in this member.

  • policies: A collection that holds, for each policy, the total number of times that the policy was found to be incompatible with the one requested by a remote DataReader that matched the Topic and with a common partition. See QosPolicyCountSeq and QosPolicyCount for more information the information that is stored for each policy.

3.1.3.13. PublicationMatchedStatus

This status changes every time the DataWriter finds a DataReader that matches the Topic and has a common partition and a compatible QoS, or has ceased to be matched with a DataReader that was previously considered to be matched. See PublicationMatchedStatus.

List of status data members:

3.1.4. Conditions and Wait-sets

Conditions (in conjunction with wait-sets) provide an alternative mechanism to allow the middleware to notify communication status changes (including arrival of data) to the application.

This mechanism is wait-based. Its general use pattern is as follows:

The first step is usually done in an initialization phase, while the others are put in the application main loop.

class ApplicationJob
{
    WaitSet wait_set_;
    GuardCondition terminate_condition_;
    std::thread thread_;

    void main_loop()
    {
        // Main loop is repeated until the terminate condition is triggered
        while (false == terminate_condition_.get_trigger_value())
        {
            // Wait for any of the conditions to be triggered
            ReturnCode_t ret_code;
            ConditionSeq triggered_conditions;
            ret_code = wait_set_.wait(triggered_conditions, eprosima::fastdds::dds::c_TimeInfinite);
            if (RETCODE_OK != ret_code)
            {
                // ... handle error
                continue;
            }

            // Process triggered conditions
            for (Condition* cond : triggered_conditions)
            {
                StatusCondition* status_cond = dynamic_cast<StatusCondition*>(cond);
                if (nullptr != status_cond)
                {
                    Entity* entity = status_cond->get_entity();
                    StatusMask changed_statuses = entity->get_status_changes();

                    // Process status. Liveliness changed and data available are depicted as an example
                    if (changed_statuses.is_active(StatusMask::liveliness_changed()))
                    {
                        std::cout << "Liveliness changed reported for entity " <<
                            entity->get_instance_handle() <<
                            std::endl;
                    }

                    if (changed_statuses.is_active(StatusMask::data_available()))
                    {
                        std::cout << "Data avilable on reader " << entity->get_instance_handle() << std::endl;

                        FooSeq data_seq;
                        SampleInfoSeq info_seq;
                        DataReader* reader = static_cast<DataReader*>(entity);

                        // Process all the samples until no one is returned
                        while (RETCODE_OK == reader->take(data_seq, info_seq,
                                LENGTH_UNLIMITED, ANY_SAMPLE_STATE,
                                ANY_VIEW_STATE, ANY_INSTANCE_STATE))
                        {
                            // Both info_seq.length() and data_seq.length() will have the number of samples returned
                            for (FooSeq::size_type n = 0; n < info_seq.length(); ++n)
                            {
                                // Only samples with valid data should be accessed
                                if (info_seq[n].valid_data &&
                                        reader->is_sample_valid(&data_seq[n], &info_seq[n]))
                                {
                                    // Process sample on data_seq[n]
                                }
                            }

                            // must return the loaned sequences when done processing
                            reader->return_loan(data_seq, info_seq);
                        }
                    }
                }
            }
        }
    }

public:

    ApplicationJob(
            const std::vector<DataReader*>& readers,
            const std::vector<DataWriter*>& writers)
    {
        // Add a GuardCondition, so we can signal the processing thread to stop
        wait_set_.attach_condition(terminate_condition_);

        // Add the status condition of every reader and writer
        for (DataReader* reader : readers)
        {
            wait_set_.attach_condition(reader->get_statuscondition());
        }
        for (DataWriter* writer : writers)
        {
            wait_set_.attach_condition(writer->get_statuscondition());
        }

        thread_ = std::thread(&ApplicationJob::main_loop, this);
    }

    ~ApplicationJob()
    {
        // Signal the GuardCondition to force the WaitSet to wake up
        terminate_condition_.set_trigger_value(true);
        // Wait for the thread to finish
        thread_.join();
    }

};

// Application initialization
ReturnCode_t ret_code;
std::vector<DataReader*> application_readers;
std::vector<DataWriter*> application_writers;

// Create the participant, topics, readers, and writers.
ret_code = create_dds_application(application_readers, application_writers);
if (RETCODE_OK != ret_code)
{
    // ... handle error
    return;
}

{
    ApplicationJob main_loop_thread(application_readers, application_writers);

    // ... wait for application termination signaling (signal handler, user input, etc)

    // ... Destructor of ApplicationJob takes care of stopping the processing thread
}

// Destroy readers, writers, topics, and participant
destroy_dds_application();

Calling the wait() operation on the Wait-set will block the calling thread if the trigger value of all the conditions attached to it are false. The thread will wake up, and the wait() operation will return RETCODE_OK, whenever the trigger value of any of the attached conditions becomes true.

3.1.4.1. GuardCondition

A condition for which the trigger value is completely controlled by the application via its set_trigger_value() operation.

3.1.4.2. StatusCondition

A condition that triggers whenever there are changes on the communication statuses of an Entity.

The sensitivity of the StatusCondition to a particular communication status is controlled by the list of enabled_statuses set on the condition by means of the set_enabled_statuses() operation.

3.1.4.3. ReadCondition

A condition that triggers whenever the DataReader that created it contains at least a sample with SampleState, ViewState, and InstanceState matching those of the ReadCondition.

The fact that the trigger value of a ReadCondition is dependent on the presence of samples on the associated DataReader implies that a single take operation can potentially change the trigger value of several ReadCondition conditions. For example, if all samples are taken, any ReadCondition associated with the DataReader that were triggered before, will see their trigger value changed to false. Note that this does not guarantee that WaitSet objects that were separately attached to those conditions will not be woken up. Once we have trigger_value == true on a condition, it may wake up the attached Wait-set. The condition transitioning to trigger_value == false does not necessarily ‘unwakeup’ the Wait-set, as ‘unwakening’ may not be possible in general. The consequence is that an application blocked on a Wait-set may return from the wait with a list of conditions, some of which are no longer triggered. This also may be the consequence of user actions. A user manually calling set_trigger_value() could potentially trigger the same behavior. This is unavoidable if multiple threads are concurrently waiting on separate Wait-set objects and taking data associated with the same DataReader entity.

To elaborate further, consider the following example: A ReadCondition that has a sample_state_mask = {NOT_READ} will have trigger_value == true whenever a new sample arrives and will transition to false as soon as all the newly-arrived samples are either read (so their status changes to READ) or taken (so they are no longer managed by the DataReader). However, if the same ReadCondition had a sample_state_mask = {READ, NOT_READ}, then the trigger_value would only become false once all the newly-arrived samples are taken (it is not sufficient to read them as that would only change the SampleState to READ which overlaps the mask on the ReadCondition).

3.2. Domain

A domain represents a separate communication plane. It creates a logical separation among the Entities that share a common communication infrastructure. Conceptually, it can be seen as a virtual network linking all applications running on the same domain and isolating them from applications running on different domains. This way, several independent distributed applications can coexist in the same physical network without interfering, or even being aware of each other.

Every domain has a unique identifier, called domainId, that is implemented as a uint32 value. Applications that share this domainId belong to the same domain and will be able to communicate.

For an application to be added to a domain, it must create an instance of DomainParticipant with the appropriate domainId. Instances of DomainParticipant are created through the DomainParticipantFactory singleton.

Partitions introduce another entity isolation level within the domain. While DomainParticipant will be able to communicate with each other if they are in the same domain, it is still possible to isolate their Publishers and Subscribers assigning them to different Partitions.

_images/domain_class_diagram.svg

Domain class diagram

3.2.1. DomainParticipant

A DomainParticipant is the entry point of the application to a domain. Every DomainParticipant is linked to a single domain from its creation, and contains all the Entities related to that domain. It also acts as a factory for Publisher, Subscriber and Topic.

The behavior of the DomainParticipant can be modified with the QoS values specified on DomainParticipantQos. The QoS values can be set at the creation of the DomainParticipant, or modified later with DomainParticipant::set_qos() member function.

As an Entity, DomainParticipant accepts a DomainParticipantListener that will be notified of status changes on the DomainParticipant instance.

3.2.1.1. DomainParticipantQos

DomainParticipantQos controls the behavior of the DomainParticipant. Internally it contains the following QosPolicy objects:

Important

The only mutable field in WireProtocolConfigQos is m_DiscoveryServers, which is contained in discovery_config within builtin (see Modifying remote servers list at run time).

Important

Upon the call to create_participant(), if Fast DDS is compiled with statistics support (enabled by default, see CMake options), the internal DomainParticipantQos may differ from the input DomainParticipantQos (see Statistics Module Settings). This entails that applications willing to further modify the DomainParticipantQos after DomainParticipant creation should:

  1. Retrieve the internal DomainParticipantQos by the means of DomainParticipant::get_qos().

  2. Perform the desired modifications.

  3. Update the DomainParticipantQos by the means of DomainParticipant::set_qos().

Refer to the detailed description of each QosPolicy class for more information about their usage and default values.

The QoS value of a previously created DomainParticipant can be modified using the DomainParticipant::set_qos() member function. Trying to modify an immutable QosPolicy on an already enabled DomainParticipant will result on an error. In such case, no changes will be applied and the DomainParticipant will keep its previous DomainParticipantQos.

// Create a DomainParticipant with default DomainParticipantQos
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
DomainParticipantQos qos = participant->get_qos();

// Modify QoS attributes
qos.entity_factory().autoenable_created_entities = false;

// Assign the new Qos to the object
participant->set_qos(qos);
3.2.1.1.1. Default DomainParticipantQos

The default DomainParticipantQos refers to the value returned by the get_default_participant_qos() member function on the DomainParticipantFactory singleton. The special value PARTICIPANT_QOS_DEFAULT can be used as QoS argument on create_participant() or DomainParticipant::set_qos() member functions to indicate that the current default DomainParticipantQos should be used.

When the system starts, the default DomainParticipantQos is equivalent to the default constructed value DomainParticipantQos(). The default DomainParticipantQos can be modified at any time using the set_default_participant_qos() member function on the DomainParticipantFactory singleton. Modifying the default DomainParticipantQos will not affect already existing DomainParticipant instances.

// Get the current QoS or create a new one from scratch
DomainParticipantQos qos_type1 = DomainParticipantFactory::get_instance()->get_default_participant_qos();

// Modify QoS attributes
// (...)

// Set as the new default TopicQos
if (DomainParticipantFactory::get_instance()->set_default_participant_qos(qos_type1) !=
        RETCODE_OK)
{
    // Error
    return;
}

// Create a DomainParticipant with the new default DomainParticipantQos.
DomainParticipant* participant_with_qos_type1 =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant_with_qos_type1)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
DomainParticipantQos qos_type2;

// Modify QoS attributes
// (...)

// Set as the new default TopicQos
if (DomainParticipantFactory::get_instance()->set_default_participant_qos(qos_type2) !=
        RETCODE_OK)
{
    // Error
    return;
}

// Create a Topic with the new default TopicQos.
DomainParticipant* participant_with_qos_type2 =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant_with_qos_type2)
{
    // Error
    return;
}

// Resetting the default DomainParticipantQos to the original default constructed values
if (DomainParticipantFactory::get_instance()->set_default_participant_qos(PARTICIPANT_QOS_DEFAULT)
        != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following
if (DomainParticipantFactory::get_instance()->set_default_participant_qos(DomainParticipantQos())
        != RETCODE_OK)
{
    // Error
    return;
}

set_default_participant_qos() member function also accepts the value PARTICIPANT_QOS_DEFAULT as input argument. This will reset the current default DomainParticipantQos to the default constructed value DomainParticipantQos().

// Create a custom DomainParticipantQos
DomainParticipantQos custom_qos;

// Modify QoS attributes
// (...)

// Create a DomainParticipant with a custom DomainParticipantQos

DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, custom_qos);
if (nullptr == participant)
{
    // Error
    return;
}

// Set the QoS on the participant to the default
if (participant->set_qos(PARTICIPANT_QOS_DEFAULT) != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following:
if (participant->set_qos(DomainParticipantFactory::get_instance()->get_default_participant_qos())
        != RETCODE_OK)
{
    // Error
    return;
}

Note

The value PARTICIPANT_QOS_DEFAULT has different meaning depending on where it is used:

3.2.1.2. DomainParticipantExtendedQos

DomainParticipantExtendedQos is an extension of DomainParticipantQos that includes both the DomainId and the DomainParticipantQos objects of a DomainParticipant. This class is useful for simplifying the creation and configuration of a DomainParticipant, as it allows specifying all necessary settings in a single object.

This DomainParticipantExtendedQos can be obtained from the loaded profiles with get_participant_extended_qos_from_profile() and then create DomainParticipant with those DomainParticipantExtendedQos. The QoS value of a previously created DomainParticipant can be modified similarly as when creating the DomainParticipant from DomainParticipantQos.

// Create a DomainParticipant with DomainParticipantExtendedQos from profile
DomainParticipantExtendedQos profile_extended_qos;
DomainParticipantFactory::get_instance()->get_participant_extended_qos_from_profile("participant_profile",
        profile_extended_qos);

DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(profile_extended_qos);
if (nullptr == participant)
{
    // Error
    return;
}

It is also possible to fill a DomainParticipantExtendedQos object directly from a raw XML string without the need to previously load any profile. Please refer to Get QoS from raw XML profiles section for more information.

3.2.2. DomainParticipantListener

DomainParticipantListener is an abstract class defining the callbacks that will be triggered in response to state changes on the DomainParticipant. By default, all these callbacks are empty and do nothing. The user should implement a specialization of this class overriding the callbacks that are needed on the application. Callbacks that are not overridden will maintain their empty implementation.

DomainParticipantListener inherits from TopicListener, PublisherListener, and SubscriberListener. Therefore, it has the ability to react to every kind of event that is reported to any of its attached Entities. Since events are always notified to the most specific Entity Listener that can handle the event, callbacks that DomainParticipantListener inherits from other Listeners will only be called if no other Entity was able to handle the event, either because it has no Listener attached, or because the callback is disabled by the StatusMask on the Entity.

Additionally, DomainParticipantListener adds the following non-standard callbacks:

  • on_participant_discovery(): A new DomainParticipant is discovered in the same domain, a previously known DomainParticipant has been removed, or some DomainParticipant has changed its QoS. This method provides an overload with an additional boolean output parameter so a discovery callback can tell the middleware if a newly discovered participant has to be ignored via the use of the ignore_participant(). This overload should be used when there is a need to ignore participants inside the discovery callback, since calling ignore_participant() inside the listener might deadlock. If both callbacks are implemented, the discovery callback with the should_be_ignored boolean flag takes precedence. The second discovery callback is only executed if the discovered DomainParticipant is not ignored in the first callback (should_be_ignored parameter returns false).

  • on_data_reader_discovery(): A new DataReader is discovered in the same domain, a previously known DataReader has been removed, or some DataReader has changed its QoS.

  • on_data_writer_discovery(): A new DataWriter is discovered in the same domain, a previously known DataWriter has been removed, or some DataWriter has changed its QoS.

  • onParticipantAuthentication(): Informs about the result of the authentication process of a remote DomainParticipant (either on failure or success).

Important

For more information about callbacks and its hierarchy, please refer to Listener.

class CustomDomainParticipantListener : public DomainParticipantListener
{

public:

    CustomDomainParticipantListener()
        : DomainParticipantListener()
    {
    }

    virtual ~CustomDomainParticipantListener()
    {
    }

    void on_participant_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::ParticipantDiscoveryStatus status,
            const ParticipantBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        if (status == eprosima::fastdds::rtps::ParticipantDiscoveryStatus::DISCOVERED_PARTICIPANT)
        {
            std::cout << "New participant discovered" << std::endl;
            // The following line can be modified to evaluate whether the discovered participant should be ignored
            // (usually based on fields present in the discovery information)
            bool ignoring_condition = false;
            if (ignoring_condition)
            {
                should_be_ignored = true; // Request the ignoring of the discovered participant
            }
        }
        else if (status == eprosima::fastdds::rtps::ParticipantDiscoveryStatus::REMOVED_PARTICIPANT ||
                status == eprosima::fastdds::rtps::ParticipantDiscoveryStatus::DROPPED_PARTICIPANT)
        {
            std::cout << "Participant lost" << std::endl;
        }
    }

#if HAVE_SECURITY
    void onParticipantAuthentication(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::ParticipantAuthenticationInfo&& info) override
    {
        if (info.status == eprosima::fastdds::rtps::ParticipantAuthenticationInfo::AUTHORIZED_PARTICIPANT)
        {
            std::cout << "A participant was authorized" << std::endl;
        }
        else if (info.status == eprosima::fastdds::rtps::ParticipantAuthenticationInfo::UNAUTHORIZED_PARTICIPANT)
        {
            std::cout << "A participant failed authorization" << std::endl;
        }
    }

#endif // if HAVE_SECURITY

    void on_data_reader_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::ReaderDiscoveryStatus reason,
            const eprosima::fastdds::rtps::SubscriptionBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        if (reason == eprosima::fastdds::rtps::ReaderDiscoveryStatus::DISCOVERED_READER)
        {
            std::cout << "New datareader discovered" << std::endl;
            // The following line can be modified to evaluate whether the discovered datareader should be ignored
            // (usually based on fields present in the discovery information)
            bool ignoring_condition = false;
            if (ignoring_condition)
            {
                should_be_ignored = true; // Request the ignoring of the discovered datareader
            }
        }
        else if (reason == eprosima::fastdds::rtps::ReaderDiscoveryStatus::REMOVED_READER)
        {
            std::cout << "Datareader lost" << std::endl;
        }
    }

    void on_data_writer_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::WriterDiscoveryStatus reason,
            const eprosima::fastdds::dds::PublicationBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        static_cast<void>(participant);
        static_cast<void>(info);

        should_be_ignored = false;
        if (reason == eprosima::fastdds::rtps::WriterDiscoveryStatus::DISCOVERED_WRITER)
        {
            std::cout << "New datawriter discovered" << std::endl;
            // The following line can be modified to evaluate whether the discovered datawriter should be ignored
            // (usually based on fields present in the discovery information)
            bool ignoring_condition = false;
            if (ignoring_condition)
            {
                should_be_ignored = true; // Request the ignoring of the discovered datawriter
            }
        }
        else if (reason == eprosima::fastdds::rtps::WriterDiscoveryStatus::REMOVED_WRITER)
        {
            std::cout << "Datawriter lost" << std::endl;
        }
    }

};

3.2.3. DomainParticipantFactory

The sole purpose of this class is to allow the creation and destruction of DomainParticipant objects. DomainParticipantFactory itself has no factory, it is a singleton object that can be accessed through the get_instance() static member function on the DomainParticipantFactory class.

The behavior of the DomainParticipantFactory can be modified with the QoS values specified on DomainParticipantFactoryQos. Since the DomainParticipantFactory is a singleton, its QoS can only be modified with the DomainParticipantFactory::set_qos() member function.

DomainParticipantFactory does not accept any Listener, since it is not an Entity.

3.2.3.1. DomainParticipantFactoryQos

DomainParticipantFactoryQos controls the behavior of the DomainParticipantFactory. Internally it contains the following QosPolicy objects:

Since the DomainParticipantFactory is a singleton, its QoS can only be modified with the DomainParticipantFactory::set_qos() member function.

DomainParticipantFactoryQos qos;

// Setting autoenable_created_entities to true makes the created DomainParticipants
// to be enabled upon creation
qos.entity_factory().autoenable_created_entities = true;
if (DomainParticipantFactory::get_instance()->set_qos(qos) != RETCODE_OK)
{
    // Error
    return;
}

// Create a DomainParticipant with the new DomainParticipantFactoryQos.
// The returned DomainParticipant is already enabled
DomainParticipant* enabled_participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == enabled_participant)
{
    // Error
    return;
}

// Setting autoenable_created_entities to false makes the created DomainParticipants
// to be disabled upon creation
qos.entity_factory().autoenable_created_entities = false;
if (DomainParticipantFactory::get_instance()->set_qos(qos) != RETCODE_OK)
{
    // Error
    return;
}

// Create a DomainParticipant with the new DomainParticipantFactoryQos.
// The returned DomainParticipant is disabled and will need to be enabled explicitly
DomainParticipant* disabled_participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == disabled_participant)
{
    // Error
    return;
}
3.2.3.2. Loading profiles from an XML file

To create Entities based on XML profiles, the file containing such profiles must be loaded first.

If the profile is described in one of the default loaded files, it will be automatically available on initialization. Otherwise, load_XML_profiles_file() member function can be used to load the profiles in the XML. See section XML profiles for more information regarding XML profile format and automatic loading.

Once loaded, the name of the profiles can be used to create Entities that will have QoS settings according to the profile specifications.

// Load the XML with the profiles
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");

// Profiles can now be used to create Entities
DomainParticipant* participant_with_profile =
        DomainParticipantFactory::get_instance()->create_participant_with_profile(0, "participant_profile");
if (nullptr == participant_with_profile)
{
    // Error
    return;
}

3.2.4. Creating a DomainParticipant

Creation of a DomainParticipant is done with the create_participant() member function on the DomainParticipantFactory singleton, that acts as a factory for the DomainParticipant. Then, when the lifecycle of the participant finishes, every participant must be deleted with delete_participant(). Please refer to Deleting a DomainParticipant for further details on the deletion of a participant.

Mandatory arguments are:

  • The DomainId that identifies the domain where the DomainParticipant will be created.

  • The DomainParticipantQos describing the behavior of the DomainParticipant. If the provided value is PARTICIPANT_QOS_DEFAULT, the value of the DomainParticipantQos is used.

Alternatively, instead of the two mandatory arguments above, you can use:

Optional arguments are:

  • A Listener derived from DomainParticipantListener, implementing the callbacks that will be triggered in response to events and state changes on the DomainParticipant. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the DomainParticipantListener.

Warning

Following the DDSI-RTPS V2.2 standard (Section 9.6.1.1), the default ports are calculated depending on the DomainId, as it is explained in section Well Known Ports. Thus, it is encouraged to use DomainId lower than 200 (over DomainId 233 default port assign will fail consistently).

create_participant() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

// Create a DomainParticipant with default DomainParticipantQos and no Listener
// The value PARTICIPANT_QOS_DEFAULT is used to denote the default QoS.
DomainParticipant* participant_with_default_attributes =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant_with_default_attributes)
{
    // Error
    return;
}

// A custom DomainParticipantQos can be provided to the creation method
DomainParticipantQos custom_qos;

// Modify QoS attributes
// (...)

DomainParticipant* participant_with_custom_qos =
        DomainParticipantFactory::get_instance()->create_participant(0, custom_qos);
if (nullptr == participant_with_custom_qos)
{
    // Error
    return;
}

// Create a DomainParticipant with default QoS and a custom Listener.
// CustomDomainParticipantListener inherits from DomainParticipantListener.
// The value PARTICIPANT_QOS_DEFAULT is used to denote the default QoS.
CustomDomainParticipantListener custom_listener;
DomainParticipant* participant_with_default_qos_and_custom_listener =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT,
                &custom_listener);
if (nullptr == participant_with_default_qos_and_custom_listener)
{
    // Error
    return;
}
3.2.4.1. Profile based creation of a DomainParticipant

Instead of using a DomainParticipantQos, the name of a profile can be used to create a DomainParticipant with the create_participant_with_profile() member function on the DomainParticipantFactory singleton.

Mandatory arguments are:

  • The DomainId that identifies the domain where the DomainParticipant will be created. Do not use DomainId higher than 200 (see Creating a DomainParticipant).

  • The name of the profile to be applied to the DomainParticipant.

Optional arguments are:

  • A Listener derived from DomainParticipantListener, implementing the callbacks that will be triggered in response to events and state changes on the DomainParticipant. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the DomainParticipantListener. By default all events are enabled.

create_participant_with_profile() will return a null pointer if there was an error during the operation, e.g if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

Note

XML profiles must have been loaded previously. See Loading profiles from an XML file.

// First load the XML with the profiles
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");

// Create a DomainParticipant using a profile and no Listener
DomainParticipant* participant_with_profile =
        DomainParticipantFactory::get_instance()->create_participant_with_profile(0, "participant_profile");
if (nullptr == participant_with_profile)
{
    // Error
    return;
}

// Create a DomainParticipant using a profile and a custom Listener.
// CustomDomainParticipantListener inherits from DomainParticipantListener.
CustomDomainParticipantListener custom_listener;
DomainParticipant* participant_with_profile_and_custom_listener =
        DomainParticipantFactory::get_instance()->create_participant_with_profile(0, "participant_profile",
                &custom_listener);
if (nullptr == participant_with_profile_and_custom_listener)
{
    // Error
    return;
}
3.2.4.2. Default profile DomainParticipant creation

If there is a profile already exported in the environment (please refer to XML profiles for related information), creating a DomainParticipant with the create_participant_with_default_profile() member function on the DomainParticipantFactory singleton would use that settings to configure the participant. If the profile has not been exported, the DomainParticipant will be created with the default values per DomainParticipantQos, and 0 as DomainId.

Optional arguments are:

  • A Listener derived from DomainParticipantListener, implementing the callbacks that will be triggered in response to events and state changes on the DomainParticipant. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the DomainParticipantListener. By default all events are enabled.

create_participant_with_default_profile() will return a null pointer if there was an error during the operation. It is advisable to check that the returned value is a valid pointer.

Note

XML profiles must have been loaded previously. See XML profiles.

// Create a DomainParticipant using the environment profile and no Listener
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant_with_default_profile();
if (nullptr == participant)
{
    // Error
    return;
}

// Create a DomainParticipant using the environment profile and a custom Listener.
// CustomDomainParticipantListener inherits from DomainParticipantListener.
CustomDomainParticipantListener custom_listener;
DomainParticipant* participant_with_custom_listener =
        DomainParticipantFactory::get_instance()->create_participant_with_default_profile(
    &custom_listener, StatusMask::none());
if (nullptr == participant_with_custom_listener)
{
    // Error
    return;
}
3.2.4.3. Deleting a DomainParticipant

A DomainParticipant shall be deleted with the delete_participant() member function on the DomainParticipantFactory singleton.

Important

A DomainParticipant can only be deleted if all Entities belonging to the participant (Publisher, Subscriber or Topic) have already been deleted. Otherwise, the function will issue an error and the DomainParticipant will not be deleted. This can be performed either by using the delete_contained_entities() member function of the DomainParticipant or manually deleting each entity with the corresponding delete_ method from the DomainParticipant e.g delete_publisher(), delete_subscriber(), delete_topic(), etc.

// Create a DomainParticipant
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Use the DomainParticipant to communicate
// (...)

// Delete entities created by the DomainParticipant
if (participant->delete_contained_entities() != RETCODE_OK)
{
    // DomainParticipant failed to delete the entities it created.
    return;
}

// Delete the DomainParticipant
if (DomainParticipantFactory::get_instance()->delete_participant(participant) != RETCODE_OK)
{
    // Error
    return;
}

3.2.5. Partitions

Partitions introduce a logical entity isolation level concept inside the physical isolation induced by a Domain. They represent another level to separate Publishers and Subscribers beyond Domain and Topic. For a Publisher to communicate with a Subscriber, they have to belong at least to one common partition. In this sense, partitions represent a light mechanism to provide data separation among endpoints:

  • Unlike Domain and Topic, Partitions can be changed dynamically during the life cycle of the endpoint with little cost. Specifically, no new threads are launched, no new memory is allocated, and the change history is not affected. Beware that modifying the Partition membership of endpoints will trigger the announcement of the new QoS configuration, and as a result, new endpoint matching may occur, depending on the new Partition configuration. Changes on the memory allocation and running threads may occur due to the matching of remote endpoints.

  • Unlike Domain and Topic, an endpoint can belong to several Partitions at the same time. For certain data to be shared over different Topics, there must be a different Publisher for each Topic, each of them sharing its own history of changes. On the other hand, a single Publisher can share the same data over different Partitions using a single topic data change, thus reducing network overload.

The Partition membership of an endpoint can be configured on the PartitionQosPolicy data member of the PublisherQos or SubscriberQos objects. This member holds a list of Partition name strings. If no Partition is defined for an entity, it will be automatically included in the default nameless Partition. Therefore, a Publisher and a Subscriber that specify no Partition will still be able to communicate through the default nameless Partition.

Warning

Partitions are linked to the endpoint and not to the changes. This means that the endpoint history is oblivious to modifications in the Partitions. For example, if a Publisher switches Partitions and afterwards needs to resend some older change again, it will deliver it to the new Partition set, regardless of which Partitions were defined when the change was created. This means that a late joiner Subscriber may receive changes that were created when another set of Partitions was active.

3.2.5.1. Wildcards in Partitions

Partition name entries can have wildcards following the naming conventions defined by the POSIX fnmatch API (1003.2-1992 section B.6). Entries with wildcards can match several names, allowing an endpoint to easily be included in several Partitions. Two Partition names with wildcards will match if either of them matches the other one according to fnmatch. That is, the matching is checked both ways. For example, consider the following configuration:

  • A Publisher with Partition part*

  • A Subscriber with Partition partition*

Even though partition* does not match part*, these Publisher and Subscriber will communicate between them because part* matches partition*.

Note that a Partition with name * will match any other partition except the default Partition.

3.2.5.2. Full example

Given a system with the following Partition configuration:

Participant_1

Pub_11

{“Partition_1”, “Partition_2”}

Pub_12

{“*”}

Participant_2

Pub_21

{}

Pub_22

{“Partition*”}

Participant_3

Subs_31

{“Partition_1”}

Subs_32

{“Partition_2”}

Subs_33

{“Partition_3”}

Subs_34

{}

The endpoints will finally match the Partitions depicted on the following table. Note that Pub_12 does not match the default Partition.

Participant_1

Participant_2

Participant_3

Pub_11

Pub_12

Pub_21

Pub_22

Subs_31

Subs_32

Subs_33

Subs_34

Partition_1

Partition_2

Partition_3

{default}

The following table provides the communication matrix for the given example:

Participant_1

Participant_2

Pub_11

Pub_12

Pub_21

Pub_22

Participant_3

Subs_31

Subs_32

Subs_33

Subs_34

The following piece of code shows the set of parameters needed for the use case depicted in this example.

PublisherQos pub_11_qos;
pub_11_qos.partition().push_back("Partition_1");
pub_11_qos.partition().push_back("Partition_2");

PublisherQos pub_12_qos;
pub_12_qos.partition().push_back("*");

PublisherQos pub_21_qos;
//No partitions defined for pub_21

PublisherQos pub_22_qos;
pub_22_qos.partition().push_back("Partition*");

SubscriberQos subs_31_qos;
subs_31_qos.partition().push_back("Partition_1");

SubscriberQos subs_32_qos;
subs_32_qos.partition().push_back("Partition_2");

SubscriberQos subs_33_qos;
subs_33_qos.partition().push_back("Partition_3");

SubscriberQos subs_34_qos;
//No partitions defined for subs_34
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <data_writer profile_name="pub_11">
        <qos>
            <partition>
                <names>
                    <name>Partition_1</name>
                    <name>Partition_2</name>
                </names>
            </partition>
        </qos>
    </data_writer>

    <data_writer profile_name="pub_12">
        <qos>
            <partition>
                <names>
                    <name>*</name>
                </names>
            </partition>
        </qos>
    </data_writer>

    <data_writer profile_name="pub_22">
        <qos>
            <partition>
                <names>
                    <name>Partition*</name>
                </names>
            </partition>
        </qos>
    </data_writer>

    <data_reader profile_name="subs_31">
        <qos>
            <partition>
                <names>
                    <name>Partition_1</name>
                </names>
            </partition>
        </qos>
    </data_reader>

    <data_reader profile_name="subs_32">
        <qos>
            <partition>
                <names>
                    <name>Partition_2</name>
                </names>
            </partition>
        </qos>
    </data_reader>

    <data_reader profile_name="subs_33">
        <qos>
            <partition>
                <names>
                    <name>Partition_3</name>
                </names>
            </partition>
        </qos>
    </data_reader>
</profiles>

3.3. Publisher

A publication is defined by the association of a DataWriter to a Publisher. To start publishing the values of a data instance, the application creates a new DataWriter in a Publisher. This DataWriter will be bound to the Topic that describes the data type that is being transmitted. Remote subscriptions that match with this Topic will be able to receive the data value updates from the DataWriter.

_images/publisher_class_diagram.svg

3.3.1. Publisher

The Publisher acts on behalf of one or several DataWriter objects that belong to it. It serves as a container that allows grouping different DataWriter objects under a common configuration given by the PublisherQos of the Publisher.

DataWriter objects that belong to the same Publisher do not have any other relation among each other beyond the PublisherQos of the Publisher and act independently otherwise. Specifically, a Publisher can host DataWriter objects for different Topics and data types.

3.3.1.1. PublisherQos

PublisherQos controls the behavior of the Publisher. Internally it contains the following QosPolicy objects:

Refer to the detailed description of each QosPolicy class for more information about their usage and default values.

The QoS value of a previously created Publisher can be modified using the Publisher::set_qos() member function.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Publisher with default PublisherQos
Publisher* publisher =
        participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (nullptr == publisher)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
PublisherQos qos = publisher->get_qos();

// Modify QoS attributes
// (...)

// Assign the new Qos to the object
publisher->set_qos(qos);
3.3.1.1.1. Default PublisherQos

The default PublisherQos refers to the value returned by the get_default_publisher_qos() member function on the DomainParticipant instance. The special value PUBLISHER_QOS_DEFAULT can be used as QoS argument on create_publisher() or Publisher::set_qos() member functions to indicate that the current default PublisherQos should be used.

When the system starts, the default PublisherQos is equivalent to the default constructed value PublisherQos(). The default PublisherQos can be modified at any time using the set_default_publisher_qos() member function on the DomainParticipant instance. Modifying the default PublisherQos will not affect already existing Publisher instances.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
PublisherQos qos_type1 = participant->get_default_publisher_qos();

// Modify QoS attributes
// (...)

// Set as the new default PublisherQos
if (participant->set_default_publisher_qos(qos_type1) != RETCODE_OK)
{
    // Error
    return;
}

// Create a Publisher with the new default PublisherQos.
Publisher* publisher_with_qos_type1 =
        participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (nullptr == publisher_with_qos_type1)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
PublisherQos qos_type2;

// Modify QoS attributes
// (...)

// Set as the new default PublisherQos
if (participant->set_default_publisher_qos(qos_type2) != RETCODE_OK)
{
    // Error
    return;
}

// Create a Publisher with the new default PublisherQos.
Publisher* publisher_with_qos_type2 =
        participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (nullptr == publisher_with_qos_type2)
{
    // Error
    return;
}

// Resetting the default PublisherQos to the original default constructed values
if (participant->set_default_publisher_qos(PUBLISHER_QOS_DEFAULT)
        != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following
if (participant->set_default_publisher_qos(PublisherQos())
        != RETCODE_OK)
{
    // Error
    return;
}

set_default_publisher_qos() member function also accepts the special value PUBLISHER_QOS_DEFAULT as input argument. This will reset the current default PublisherQos to default constructed value PublisherQos().

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a custom PublisherQos
PublisherQos custom_qos;

// Modify QoS attributes
// (...)

// Create a publisher with a custom PublisherQos
Publisher* publisher = participant->create_publisher(custom_qos);
if (nullptr == publisher)
{
    // Error
    return;
}

// Set the QoS on the publisher to the default
if (publisher->set_qos(PUBLISHER_QOS_DEFAULT) != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following:
if (publisher->set_qos(participant->get_default_publisher_qos())
        != RETCODE_OK)
{
    // Error
    return;
}

Note

The value PUBLISHER_QOS_DEFAULT has different meaning depending on where it is used:

3.3.2. PublisherListener

PublisherListener is an abstract class defining the callbacks that will be triggered in response to state changes on the Publisher. By default, all these callbacks are empty and do nothing. The user should implement a specialization of this class overriding the callbacks that are needed on the application. Callbacks that are not overridden will maintain their empty implementation.

PublisherListener inherits from DataWriterListener. Therefore, it has the ability to react to all events that are reported to the DataWriter. Since events are always notified to the most specific Entity Listener that can handle the event, callbacks that PublisherListener inherits from DataWriterListener will only be called if the triggering DataWriter has no Listener attached, or if the callback is disabled by the StatusMask on the DataWriter.

PublisherListener does not add any new callback. Please, refer to the DataWriterListener for the list of inherited callbacks and override examples.

3.3.3. Creating a Publisher

A Publisher always belongs to a DomainParticipant. Creation of a Publisher is done with the create_publisher() member function on the DomainParticipant instance, that acts as a factory for the Publisher.

Mandatory arguments are:

Optional arguments are:

  • A Listener derived from PublisherListener, implementing the callbacks that will be triggered in response to events and state changes on the Publisher. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the PublisherListener. By default all events are enabled.

create_publisher() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Publisher with default PublisherQos and no Listener
// The value PUBLISHER_QOS_DEFAULT is used to denote the default QoS.
Publisher* publisher_with_default_qos =
        participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (nullptr == publisher_with_default_qos)
{
    // Error
    return;
}

// A custom PublisherQos can be provided to the creation method
PublisherQos custom_qos;

// Modify QoS attributes
// (...)

Publisher* publisher_with_custom_qos =
        participant->create_publisher(custom_qos);
if (nullptr == publisher_with_custom_qos)
{
    // Error
    return;
}

// Create a Publisher with default QoS and a custom Listener.
// CustomPublisherListener inherits from PublisherListener.
// The value PUBLISHER_QOS_DEFAULT is used to denote the default QoS.
CustomPublisherListener custom_listener;
Publisher* publisher_with_default_qos_and_custom_listener =
        participant->create_publisher(PUBLISHER_QOS_DEFAULT, &custom_listener);
if (nullptr == publisher_with_default_qos_and_custom_listener)
{
    // Error
    return;
}
3.3.3.1. Profile based creation of a Publisher

Instead of using a PublisherQos, the name of a profile can be used to create a Publisher with the create_publisher_with_profile() member function on the DomainParticipant instance.

Mandatory arguments are:

  • A string with the name that identifies the Publisher.

Optional arguments are:

  • A Listener derived from PublisherListener, implementing the callbacks that will be triggered in response to events and state changes on the Publisher. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the PublisherListener. By default all events are enabled.

create_publisher_with_profile() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

Note

XML profiles must have been loaded previously. See Loading profiles from an XML file.

// First load the XML with the profiles
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Publisher using a profile and no Listener
Publisher* publisher_with_profile =
        participant->create_publisher_with_profile("publisher_profile");
if (nullptr == publisher_with_profile)
{
    // Error
    return;
}

// Create a Publisher using a profile and a custom Listener.
// CustomPublisherListener inherits from PublisherListener.
CustomPublisherListener custom_listener;
Publisher* publisher_with_profile_and_custom_listener =
        participant->create_publisher_with_profile("publisher_profile", &custom_listener);
if (nullptr == publisher_with_profile_and_custom_listener)
{
    // Error
    return;
}
3.3.3.2. Deleting a Publisher

A Publisher can be deleted with the delete_publisher() member function on the DomainParticipant instance where the Publisher was created.

Note

A Publisher can only be deleted if all Entities belonging to the Publisher (DataWriters) have already been deleted. Otherwise, the function will issue an error and the Publisher will not be deleted. This can be performed by using the delete_contained_entities() member function of the Publisher.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Publisher
Publisher* publisher =
        participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (nullptr == publisher)
{
    // Error
    return;
}

// Use the Publisher to communicate
// (...)

// Delete the entities the Publisher created.
if (publisher->delete_contained_entities() != RETCODE_OK)
{
    // Publisher failed to delete the entities it created.
    return;
}

// Delete the Publisher
if (participant->delete_publisher(publisher) != RETCODE_OK)
{
    // Error
    return;
}

3.3.4. DataWriter

A DataWriter is attached to exactly one Publisher that acts as a factory for it. Additionally, each DataWriter is bound to a single Topic since its creation. This Topic must exist prior to the creation of the DataWriter, and must be bound to the data type that the DataWriter wants to publish.

The effect of creating a new DataWriter in a Publisher for a specific Topic is to initiate a new publication with the name and data type described by the Topic.

Once the DataWriter is created, the application can inform of changes in the data value using the write() member function on the DataWriter. These changes will be transmitted to all subscriptions matched with this publication.

3.3.4.1. DataWriterQos

DataWriterQos controls the behavior of the DataWriter. Internally it contains the following QosPolicy objects:

The following non-consolidated property-assigned QoS apply to DataWriters:

Property name

Non-consolidated QoS

fastdds.push_mode

DataWriter operating mode QoS Policy

partitions

Endpoint Partitions

Refer to the detailed description of each QosPolicy class for more information about their usage and default values.

Note

Reliability kind (whether the publication is reliable or best effort) is not mutable. However, the max_blocking_time data member of ReliabilityQosPolicy can be modified any time.

Note

Not all data members of RTPSReliableWriterQos are mutable, please refer to RTPSReliableWriterQos for more information.

The QoS value of a previously created DataWriter can be modified using the DataWriter::set_qos() member function.

// Create a DataWriter with default DataWriterQos
DataWriter* data_writer =
        publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == data_writer)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
DataWriterQos qos = data_writer->get_qos();

// Modify QoS attributes
// (...)

// Assign the new Qos to the object
data_writer->set_qos(qos);
3.3.4.1.1. Default DataWriterQos

The default DataWriterQos refers to the value returned by the get_default_datawriter_qos() member function on the Publisher instance. The special value DATAWRITER_QOS_DEFAULT can be used as QoS argument on create_datawriter() or DataWriter::set_qos() member functions to indicate that the current default DataWriterQos should be used.

When the system starts, the default DataWriterQos is equivalent to the default constructed value DataWriterQos(). The default DataWriterQos can be modified at any time using the set_default_datawriter_qos() member function on the Publisher instance. Modifying the default DataWriterQos will not affect already existing DataWriter instances.

// Get the current QoS or create a new one from scratch
DataWriterQos qos_type1 = publisher->get_default_datawriter_qos();

// Modify QoS attributes
// (...)

// Set as the new default DataWriterQos
if (publisher->set_default_datawriter_qos(qos_type1) != RETCODE_OK)
{
    // Error
    return;
}

// Create a DataWriter with the new default DataWriterQos.
DataWriter* data_writer_with_qos_type1 =
        publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == data_writer_with_qos_type1)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
DataWriterQos qos_type2;

// Modify QoS attributes
// (...)

// Set as the new default DataWriterQos
if (publisher->set_default_datawriter_qos(qos_type2) != RETCODE_OK)
{
    // Error
    return;
}

// Create a DataWriter with the new default DataWriterQos.
DataWriter* data_writer_with_qos_type2 =
        publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == data_writer_with_qos_type2)
{
    // Error
    return;
}

// Resetting the default DataWriterQos to the original default constructed values
if (publisher->set_default_datawriter_qos(DATAWRITER_QOS_DEFAULT)
        != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following
if (publisher->set_default_datawriter_qos(DataWriterQos())
        != RETCODE_OK)
{
    // Error
    return;
}

set_default_datawriter_qos() member function also accepts the special value DATAWRITER_QOS_DEFAULT as input argument. This will reset the current default DataWriterQos to default constructed value DataWriterQos().

// Create a custom DataWriterQos
DataWriterQos custom_qos;

// Modify QoS attributes
// (...)

// Create a DataWriter with a custom DataWriterQos
DataWriter* data_writer = publisher->create_datawriter(topic, custom_qos);
if (nullptr == data_writer)
{
    // Error
    return;
}

// Set the QoS on the DataWriter to the default
if (data_writer->set_qos(DATAWRITER_QOS_DEFAULT) != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following:
if (data_writer->set_qos(publisher->get_default_datawriter_qos())
        != RETCODE_OK)
{
    // Error
    return;
}

Note

The value DATAWRITER_QOS_DEFAULT has different meaning depending on where it is used:

3.3.5. DataWriterListener

DataWriterListener is an abstract class defining the callbacks that will be triggered in response to state changes on the DataWriter. By default, all these callbacks are empty and do nothing. The user should implement a specialization of this class overriding the callbacks that are needed on the application. Callbacks that are not overridden will maintain their empty implementation.

DataWriterListener defines the following callbacks:

  • on_publication_matched(): The DataWriter has found a DataReader that matches the Topic and has a common partition and a compatible QoS, or has ceased to be matched with a DataReader that was previously considered to be matched.

  • on_offered_deadline_missed(): The DataWriter failed to provide data within the deadline period configured on its DataWriterQos. It will be called for each deadline period and data instance for which the DataWriter failed to provide data.

  • on_offered_incompatible_qos(): The DataWriter has found a DataReader that matches the Topic and has a common partition, but with a requested QoS that is incompatible with the one defined on the DataWriter.

  • on_liveliness_lost(): The DataWriter did not respect the liveliness configuration on its DataWriterQos, and therefore, DataReader entities will consider the DataWriter as no longer active.

  • on_unacknowledged_sample_removed(): The Datawriter has removed a sample that has not been acknowledged by every matched DataReader.

3.3.5.1. on_unacknowledged_sample_removed callback

on_unacknowledged_sample_removed() non-standard callback notifies the user when a sample has been removed without being sent/received by the matched DataReaders. This could happen in constrained networks or if the publication throughput is too demanding. This callback can be used to detect these situations so the publishing application can apply some solution to ease this issue like reducing the publication rate.

The criteria to consider that a sample has been removed without being acknowledged depends on the ReliabilityQosPolicy:

  • BEST_EFFORT_RELIABILITY_QOS DataWriters will notify that a sample has been removed while unacknowledged if the sample has not been sent through the transport.

  • RELIABLE_RELIABILITY_QOS DataWriters consider samples to have been removed unacknowledged if not every matched DataReader has confirmed its reception by sending the corresponding meta-traffic ACK message. Consequently, a sample that is notified as removed unacknowledged might be received by one or more DataReaders, but not by every matched one, or at least, the ACK message has not been received at the moment of sample removal. A race condition is inevitable in this case, because when the sample is removed, the ACK from some matched DataReader is missing, but that means that it might have been lost in the transmission or that the message is still coming through and it will be received after the sample removal. Thus, this criteria may include false positives, but from the user’s point of view, it is more meaningful to know when the sample has not been acknowledged by every matched DataReader even if some samples are erroneously notified.

A specific case must be considered for reliable DataWriters with DisablePositiveACKsQosPolicy enabled. This policy disables the sending of positive ACK messages, unless the sample has been lost in which case the matched DataReader notifies the loss with a negative NACK message. If no NACK has been received in the time defined in the QoS policy, the sample is considered to be received. Again, this is prone to race conditions because the NACK message might be on its way or have been lost in the network. For this specific case, where ACK messages are not going to be received, the reliable DataWriter uses the same criteria as the best effort DataWriter.

class CustomDataWriterListener : public DataWriterListener
{

public:

    CustomDataWriterListener()
        : DataWriterListener()
    {
    }

    virtual ~CustomDataWriterListener()
    {
    }

    void on_publication_matched(
            DataWriter* writer,
            const PublicationMatchedStatus& info) override
    {
        static_cast<void>(writer);
        if (info.current_count_change == 1)
        {
            std::cout << "Matched a remote Subscriber for one of our Topics" << std::endl;
        }
        else if (info.current_count_change == -1)
        {
            std::cout << "Unmatched a remote Subscriber" << std::endl;
        }
    }

    void on_offered_deadline_missed(
            DataWriter* writer,
            const OfferedDeadlineMissedStatus& status) override
    {
        static_cast<void>(writer);
        static_cast<void>(status);
        std::cout << "Some data could not be delivered on time" << std::endl;
    }

    void on_offered_incompatible_qos(
            DataWriter* writer,
            const OfferedIncompatibleQosStatus& status) override
    {
        std::cout << "Found a remote Topic with incompatible QoS (QoS ID: " << status.last_policy_id <<
            ")" << std::endl;
    }

    void on_liveliness_lost(
            DataWriter* writer,
            const LivelinessLostStatus& status) override
    {
        static_cast<void>(writer);
        static_cast<void>(status);
        std::cout << "Liveliness lost. Matched Subscribers will consider us offline" << std::endl;
    }

    void on_unacknowledged_sample_removed(
            DataWriter* writer,
            const InstanceHandle_t& instance) override
    {
        static_cast<void>(writer);
        static_cast<void>(instance);
        std::cout << "Sample removed unacknowledged" << std::endl;
    }

};

3.3.6. Creating a DataWriter

A DataWriter always belongs to a Publisher. Creation of a DataWriter is done with the create_datawriter() member function on the Publisher instance, that acts as a factory for the DataWriter.

Mandatory arguments are:

  • A Topic bound to the data type that will be transmitted.

  • The DataWriterQos describing the behavior of the DataWriter. If the provided value is DATAWRITER_QOS_DEFAULT, the value of the Default DataWriterQos is used. If the provided value is DATAWRITER_QOS_USE_TOPIC_QOS, the values of the default QoS and the provided TopicQoS are used, whereby any policy that is set on the TopicQoS overrides the corresponding policy on the default QoS.

Optional arguments are:

  • A Listener derived from DataWriterListener, implementing the callbacks that will be triggered in response to events and state changes on the DataWriter. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the DataWriterListener. By default all events are enabled.

create_datawriter() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

// Create a DataWriter with default DataWriterQos and no Listener
// The value DATAWRITER_QOS_DEFAULT is used to denote the default QoS.
DataWriter* data_writer_with_default_qos =
        publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == data_writer_with_default_qos)
{
    // Error
    return;
}

// A custom DataWriterQos can be provided to the creation method
DataWriterQos custom_qos;

// Modify QoS attributes
// (...)

DataWriter* data_writer_with_custom_qos =
        publisher->create_datawriter(topic, custom_qos);
if (nullptr == data_writer_with_custom_qos)
{
    // Error
    return;
}

// Create a DataWriter with default QoS and a custom Listener.
// CustomDataWriterListener inherits from DataWriterListener.
// The value DATAWRITER_QOS_DEFAULT is used to denote the default QoS.
CustomDataWriterListener custom_listener;
DataWriter* data_writer_with_default_qos_and_custom_listener =
        publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT, &custom_listener);
if (nullptr == data_writer_with_default_qos_and_custom_listener)
{
    // Error
    return;
}

// Create a DataWriter with default QoS and a custom TopicQos.
// The value DATAWRITER_QOS_USE_TOPIC_QOS is used to denote the default QoS
// and to override the TopicQos.
Topic* topic;
DataWriter* data_writer_with_default_qos_and_custom_topic_qos =
        publisher->create_datawriter(topic, DATAWRITER_QOS_USE_TOPIC_QOS);
if (nullptr == data_writer_with_default_qos_and_custom_topic_qos)
{
    // Error
    return;
}
3.3.6.1. Profile based creation of a DataWriter

Instead of using a DataWriterQos, the name of a profile can be used to create a DataWriter with the create_datawriter_with_profile() member function on the Publisher instance.

Mandatory arguments are:

  • A Topic bound to the data type that will be transmitted.

  • A string with the name that identifies the DataWriter.

Optional arguments are:

  • A Listener derived from DataWriterListener, implementing the callbacks that will be triggered in response to events and state changes on the DataWriter. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the DataWriterListener. By default all events are enabled.

create_datawriter_with_profile() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

Note

XML profiles must have been loaded previously. See Loading profiles from an XML file.

// First load the XML with the profiles
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");

// Create a DataWriter using a profile and no Listener
DataWriter* data_writer_with_profile =
        publisher->create_datawriter_with_profile(topic, "data_writer_profile");
if (nullptr == data_writer_with_profile)
{
    // Error
    return;
}

// Create a DataWriter using a profile and a custom Listener.
// CustomDataWriterListener inherits from DataWriterListener.
CustomDataWriterListener custom_listener;
DataWriter* data_writer_with_profile_and_custom_listener =
        publisher->create_datawriter_with_profile(topic, "data_writer_profile", &custom_listener);
if (nullptr == data_writer_with_profile_and_custom_listener)
{
    // Error
    return;
}
3.3.6.2. Creating a DataWriter with a custom PayloadPool

A custom PayloadPool can be passed as an argument during the creation of a DataWriter. This allows for customizing the management of the information exchanged between DataWriters and DataReaders. The same configuration can be set in the opposite endpoint.

// A DataWriterQos must be provided to the creation method
DataWriterQos qos;

// Create PayloadPool
std::shared_ptr<eprosima::fastdds::rtps::IPayloadPool> payload_pool =
        std::dynamic_pointer_cast<eprosima::fastdds::rtps::IPayloadPool>(std::make_shared<CustomPayloadPool>());

DataWriter* data_writer = publisher->create_datawriter(topic, qos, nullptr, StatusMask::all(), payload_pool);
if (nullptr == data_writer)
{
    // Error
    return;
}

This configuration can be performed also in the RTPS layer. The customization example applies both layers.

3.3.6.3. Deleting a DataWriter

A DataWriter can be deleted with the delete_datawriter() member function on the Publisher instance where the DataWriter was created.

// Create a DataWriter
DataWriter* data_writer =
        publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == data_writer)
{
    // Error
    return;
}

// Use the DataWriter to communicate
// (...)

// Delete the DataWriter
if (publisher->delete_datawriter(data_writer) != RETCODE_OK)
{
    // Error
    return;
}

3.3.7. Publishing data

The user informs of a change in the value of a data instance with the write() member function on the DataWriter. This change will then be communicated to every DataReader matched with the DataWriter. As a side effect, this operation asserts liveliness on the DataWriter itself, the Publisher and the DomainParticipant.

The function takes two arguments:

  • A pointer to the data instance with the new values.

  • The handler to the instance.

An empty (i.e., default constructed InstanceHandle_t) instance handler can be used for the argument handle. This indicates that the identity of the instance should be automatically deduced from the key of the instance data. Alternatively, the member function write() is overloaded to take only the pointer to the data instance, which will always deduced the identity from the key of the instance data.

If the handle is not empty, then it must correspond to the value obtained with the getKey() of the TypeSupport instance. Otherwise the write function will fail with RETCODE_PRECONDITION_NOT_MET.

// Register the data type in the DomainParticipant.
TypeSupport custom_type_support(new CustomDataType());
custom_type_support.register_type(participant, custom_type_support.get_type_name());

// Create a Topic with the registered type.
Topic* custom_topic =
        participant->create_topic("topic_name", custom_type_support.get_type_name(), TOPIC_QOS_DEFAULT);
if (nullptr == custom_topic)
{
    // Error
    return;
}

// Create a DataWriter
DataWriter* data_writer =
        publisher->create_datawriter(custom_topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == data_writer)
{
    // Error
    return;
}

// Get a data instance
void* data = custom_type_support->create_data();

// Fill the data values
// (...)

// Publish the new value, deduce the instance handle
if (data_writer->write(data, eprosima::fastdds::rtps::InstanceHandle_t()) != RETCODE_OK)
{
    // Error
    return;
}

// The data instance can be reused to publish new values,
// but delete it at the end to avoid leaks
custom_type_support->delete_data(data);
3.3.7.1. Blocking of the write operation

If the reliability kind is set to RELIABLE on the DataWriterQos, the write() operation may block. Specifically, if the limits specified in the configured resource limits have been reached, the write() operation will block waiting for space to become available. Under these circumstances, the reliability max_blocking_time configures the maximum time the write operation may block waiting. If max_blocking_time elapses before the DataWriter is able to store the modification without exceeding the limits, the write operation will fail and return TIMEOUT.

3.3.7.2. Borrowing a data buffer

When the user calls write() with a new sample value, the data is copied from the given sample to the DataWriter’s memory. For large data types this copy can consume significant time and memory resources. Instead, the DataWriter can loan a sample from its memory to the user, and the user can fill this sample with the required values. When write() is called with such a loaned sample, the DataWriter does not copy its contents, as it already owns the buffer.

To use loaned data samples in publications, perform the following steps:

  1. Get a reference to a loaned sample using loan_sample().

  2. Use the reference to build the data sample.

  3. Write the sample using write().

Once write() has been called with a loaned sample, the loan is considered returned, and it is not safe to make any changes on the contents of the sample.

If function loan_sample() is called but the sample is never written, the loan must be returned to the DataWriter using discard_loan(). Otherwise the DataWriter may run out of samples.

    // Borrow a data instance
    void* data = nullptr;
    if (RETCODE_OK == data_writer->loan_sample(data))
    {
        bool error = false;

        // Fill the data values
        // (...)

        if (error)
        {
            // Return the loan without publishing
            data_writer->discard_loan(data);
            return;
        }

        // Publish the new value
        if (data_writer->write(data, eprosima::fastdds::rtps::InstanceHandle_t()) != RETCODE_OK)
        {
            // Error
            return;
        }
    }

3.4. Subscriber

A subscription is defined by the association of a DataReader to a Subscriber. To start receiving updates of a publication, the application creates a new DataReader in a Subscriber. This DataReader will be bound to the Topic that describes the data type that is going to be received. The DataReader will then start receiving data value updates from remote publications that match this Topic.

When the Subscriber receives data, it informs the application that new data is available. Then, the application can use the DataReader to get the received data.

_images/subscriber_class_diagram.svg

Subscriber class diagram

3.4.1. Subscriber

The Subscriber acts on behalf of one or several DataReader objects that belong to it. It serves as a container that allows grouping different DataReader objects under a common configuration given by the SubscriberQos of the Subscriber.

DataReader objects that belong to the same Subscriber do not have any other relation among each other beyond the SubscriberQos of the Subscriber and act independently otherwise. Specifically, a Subscriber can host DataReader objects for different topics and data types.

3.4.1.1. SubscriberQos

SubscriberQos controls the behavior of the Subscriber. Internally it contains the following QosPolicy objects:

Refer to the detailed description of each QosPolicy class for more information about their usage and default values.

The QoS value of a previously created Subscriber can be modified using the Subscriber::set_qos() member function.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Subscriber with default SubscriberQos
Subscriber* subscriber =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
SubscriberQos qos = subscriber->get_qos();

// Modify QoS attributes
qos.entity_factory().autoenable_created_entities = false;

// Assign the new Qos to the object
subscriber->set_qos(qos);
3.4.1.1.1. Default SubscriberQos

The default SubscriberQos refers to the value returned by the get_default_subscriber_qos() member function on the DomainParticipant instance. The special value SUBSCRIBER_QOS_DEFAULT can be used as QoS argument on create_subscriber() or Subscriber::set_qos() member functions to indicate that the current default SubscriberQos should be used.

When the system starts, the default SubscriberQos is equivalent to the default constructed value SubscriberQos(). The default SubscriberQos can be modified at any time using the set_default_subscriber_qos() member function on the DomainParticipant instance. Modifying the default SubscriberQos will not affect already existing Subscriber instances.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
SubscriberQos qos_type1 = participant->get_default_subscriber_qos();

// Modify QoS attributes
// (...)

// Set as the new default SubscriberQos
if (participant->set_default_subscriber_qos(qos_type1) != RETCODE_OK)
{
    // Error
    return;
}

// Create a Subscriber with the new default SubscriberQos.
Subscriber* subscriber_with_qos_type1 =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber_with_qos_type1)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
SubscriberQos qos_type2;

// Modify QoS attributes
// (...)

// Set as the new default SubscriberQos
if (participant->set_default_subscriber_qos(qos_type2) != RETCODE_OK)
{
    // Error
    return;
}

// Create a Subscriber with the new default SubscriberQos.
Subscriber* subscriber_with_qos_type2 =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber_with_qos_type2)
{
    // Error
    return;
}

// Resetting the default SubscriberQos to the original default constructed values
if (participant->set_default_subscriber_qos(SUBSCRIBER_QOS_DEFAULT)
        != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following
if (participant->set_default_subscriber_qos(SubscriberQos())
        != RETCODE_OK)
{
    // Error
    return;
}

set_default_subscriber_qos() member function also accepts the special value SUBSCRIBER_QOS_DEFAULT as input argument. This will reset the current default SubscriberQos to default constructed value SubscriberQos().

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a custom SubscriberQos
SubscriberQos custom_qos;

// Modify QoS attributes
// (...)

// Create a subscriber with a custom SubscriberQos
Subscriber* subscriber = participant->create_subscriber(custom_qos);
if (nullptr == subscriber)
{
    // Error
    return;
}

// Set the QoS on the subscriber to the default
if (subscriber->set_qos(SUBSCRIBER_QOS_DEFAULT) != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following:
if (subscriber->set_qos(participant->get_default_subscriber_qos())
        != RETCODE_OK)
{
    // Error
    return;
}

Note

The value SUBSCRIBER_QOS_DEFAULT has different meaning depending on where it is used:

3.4.2. SubscriberListener

SubscriberListener is an abstract class defining the callbacks that will be triggered in response to state changes on the Subscriber. By default, all these callbacks are empty and do nothing. The user should implement a specialization of this class overriding the callbacks that are needed on the application. Callbacks that are not overridden will maintain their empty implementation.

SubscriberListener inherits from DataReaderListener. Therefore, it has the ability to react to all events that are reported to the DataReader. Since events are always notified to the most specific Entity Listener that can handle the event, callbacks that SubscriberListener inherits from DataReaderListener will only be called if the triggering DataReader has no Listener attached, or if the callback is disabled by the StatusMask on the DataReader.

Additionally, SubscriberListener adds the following callback:

  • on_data_on_readers(): New data is available on any DataReader belonging to this Subscriber. There is no queuing of invocations to this callback, meaning that if several new data changes are received at once, only one callback invocation may be issued for all of them, instead of one per change. If the application is retrieving the received data on this callback, it must keep reading data until no new changes are left.

Important

For more information about callbacks and its hierarchy, please refer to Listener.

class CustomSubscriberListener : public SubscriberListener
{

public:

    CustomSubscriberListener()
        : SubscriberListener()
    {
    }

    virtual ~CustomSubscriberListener()
    {
    }

    virtual void on_data_on_readers(
            Subscriber* sub)
    {
        static_cast<void>(sub);
        std::cout << "New data available" << std::endl;
    }

};

3.4.3. Creating a Subscriber

A Subscriber always belongs to a DomainParticipant. Creation of a Subscriber is done with the create_subscriber() member function on the DomainParticipant instance, that acts as a factory for the Subscriber.

Mandatory arguments are:

Optional arguments are:

  • A Listener derived from SubscriberListener, implementing the callbacks that will be triggered in response to events and state changes on the Subscriber. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the SubscriberListener. By default all events are enabled.

create_subscriber() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Subscriber with default SubscriberQos and no Listener
// The value SUBSCRIBER_QOS_DEFAULT is used to denote the default QoS.
Subscriber* subscriber_with_default_qos =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber_with_default_qos)
{
    // Error
    return;
}

// A custom SubscriberQos can be provided to the creation method
SubscriberQos custom_qos;

// Modify QoS attributes
// (...)

Subscriber* subscriber_with_custom_qos =
        participant->create_subscriber(custom_qos);
if (nullptr == subscriber_with_custom_qos)
{
    // Error
    return;
}

// Create a Subscriber with default QoS and a custom Listener.
// CustomSubscriberListener inherits from SubscriberListener.
// The value SUBSCRIBER_QOS_DEFAULT is used to denote the default QoS.
CustomSubscriberListener custom_listener;
Subscriber* subscriber_with_default_qos_and_custom_listener =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT, &custom_listener);
if (nullptr == subscriber_with_default_qos_and_custom_listener)
{
    // Error
    return;
}
3.4.3.1. Profile based creation of a Subscriber

Instead of using a SubscriberQos, the name of a profile can be used to create a Subscriber with the create_subscriber_with_profile() member function on the DomainParticipant instance.

Mandatory arguments are:

  • A string with the name that identifies the Subscriber.

Optional arguments are:

  • A Listener derived from SubscriberListener, implementing the callbacks that will be triggered in response to events and state changes on the Subscriber. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the SubscriberListener. By default all events are enabled.

create_subscriber_with_profile() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

Note

XML profiles must have been loaded previously. See Loading profiles from an XML file.

// First load the XML with the profiles
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Subscriber using a profile and no Listener
Subscriber* subscriber_with_profile =
        participant->create_subscriber_with_profile("subscriber_profile");
if (nullptr == subscriber_with_profile)
{
    // Error
    return;
}

// Create a Subscriber using a profile and a custom Listener.
// CustomSubscriberListener inherits from SubscriberListener.
CustomSubscriberListener custom_listener;
Subscriber* subscriber_with_profile_and_custom_listener =
        participant->create_subscriber_with_profile("subscriber_profile", &custom_listener);
if (nullptr == subscriber_with_profile_and_custom_listener)
{
    // Error
    return;
}
3.4.3.2. Deleting a Subscriber

A Subscriber can be deleted with the delete_subscriber() member function on the DomainParticipant instance where the Subscriber was created.

Note

A Subscriber can only be deleted if all Entities belonging to the Subscriber (DataReaders) have already been deleted. Otherwise, the function will issue an error and the Subscriber will not be deleted. This can be performed by using the delete_contained_entities() member function of the Subscriber.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Subscriber
Subscriber* subscriber =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber)
{
    // Error
    return;
}

// Use the Subscriber to communicate
// (...)

// Delete the entities the subscriber created
if (subscriber->delete_contained_entities() != RETCODE_OK)
{
    // Subscriber failed to delete the entities it created
    return;
}

// Delete the Subscriber
if (participant->delete_subscriber(subscriber) != RETCODE_OK)
{
    // Error
    return;
}

3.4.4. DataReader

A DataReader is attached to exactly one Subscriber that acts as a factory for it. Additionally, each DataReader is bound to a single Topic since its creation. This Topic must exist prior to the creation of the DataReader, and must be bound to the data type that the DataReader wants to publish.

The effect of creating a new DataReader in a Subscriber for a specific Topic is to initiate a new subscription with the name and data type described by the Topic.

Once the DataReader is created, the application will be informed when changes in the data value are received from remote publications. These changes can then be retrieved using the DataReader::read_next_sample() or DataReader::take_next_sample() member functions of the DataReader.

3.4.4.1. DataReaderQos

DataReaderQoS controls the behavior of the DataReader. Internally it contains the following QosPolicy objects:

The following non-consolidated property-assigned QoS apply to DataReaders:

Property name

Non-consolidated QoS

partitions

Endpoint Partitions

Refer to the detailed description of each QosPolicy class for more information about their usage and default values.

Note

Reliability kind (whether the publication is reliable or best effort) is not mutable. However, the max_blocking_time data member of ReliabilityQosPolicy can be modified any time.

Note

Not all data members of RTPSReliableReaderQos are mutable, please refer to RTPSReliableReaderQos for more information.

The QoS value of a previously created DataReader can be modified using the DataReader::set_qos() member function.

// Create a DataReader with default DataReaderQos
DataReader* data_reader =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
DataReaderQos qos = data_reader->get_qos();

// Modify QoS attributes
// (...)

// Assign the new Qos to the object
data_reader->set_qos(qos);
3.4.4.1.1. Default DataReaderQos

The default DataReaderQos refers to the value returned by the get_default_datareader_qos() member function on the Subscriber instance. The special value DATAREADER_QOS_DEFAULT can be used as QoS argument on create_datareader() or DataReader::set_qos() member functions to indicate that the current default DataReaderQos should be used.

When the system starts, the default DataReaderQos is equivalent to the default constructed value DataReaderQos(). The default DataReaderQos can be modified at any time using the set_default_datareader_qos() member function on the Subscriber instance. Modifying the default DataReaderQos will not affect already existing DataReader instances.

// Get the current QoS or create a new one from scratch
DataReaderQos qos_type1 = subscriber->get_default_datareader_qos();

// Modify QoS attributes
// (...)

// Set as the new default DataReaderQos
if (subscriber->set_default_datareader_qos(qos_type1) != RETCODE_OK)
{
    // Error
    return;
}

// Create a DataReader with the new default DataReaderQos.
DataReader* data_reader_with_qos_type1 =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader_with_qos_type1)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
DataReaderQos qos_type2;

// Modify QoS attributes
// (...)

// Set as the new default DataReaderQos
if (subscriber->set_default_datareader_qos(qos_type2) != RETCODE_OK)
{
    // Error
    return;
}

// Create a DataReader with the new default DataReaderQos.
DataReader* data_reader_with_qos_type2 =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader_with_qos_type2)
{
    // Error
    return;
}

// Resetting the default DataReaderQos to the original default constructed values
if (subscriber->set_default_datareader_qos(DATAREADER_QOS_DEFAULT)
        != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following
if (subscriber->set_default_datareader_qos(DataReaderQos())
        != RETCODE_OK)
{
    // Error
    return;
}

set_default_datareader_qos() member function also accepts the special value DATAREADER_QOS_DEFAULT as input argument. This will reset the current default DataReaderQos to default constructed value DataReaderQos().

// Create a custom DataReaderQos
DataReaderQos custom_qos;

// Modify QoS attributes
// (...)

// Create a DataWriter with a custom DataReaderQos
DataReader* data_reader = subscriber->create_datareader(topic, custom_qos);
if (nullptr == data_reader)
{
    // Error
    return;
}

// Set the QoS on the DataWriter to the default
if (data_reader->set_qos(DATAREADER_QOS_DEFAULT) != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following:
if (data_reader->set_qos(subscriber->get_default_datareader_qos())
        != RETCODE_OK)
{
    // Error
    return;
}

Note

The value DATAREADER_QOS_DEFAULT has different meaning depending on where it is used:

3.4.5. DataReaderListener

DataReaderListener is an abstract class defining the callbacks that will be triggered in response to state changes on the DataReader. By default, all these callbacks are empty and do nothing. The user should implement a specialization of this class overriding the callbacks that are needed on the application. Callbacks that are not overridden will maintain their empty implementation.

DataReaderListener defines the following callbacks:

  • on_data_available(): There is new data available for the application on the DataReader. There is no queuing of invocations to this callback, meaning that if several new data changes are received at once, only one callback invocation may be issued for all of them, instead of one per change. If the application is retrieving the received data on this callback, it must keep reading data until no new changes are left.

  • on_subscription_matched(): The DataReader has found a DataWriter that matches the Topic and has a common partition and a compatible QoS, or has ceased to be matched with a DataWriter that was previously considered to be matched. It is also triggered when a matched DataWriter has changed its DataWriterQos.

  • on_requested_deadline_missed(): The DataReader did not receive data within the deadline period configured on its DataReaderQos. It will be called for each deadline period and data instance for which the DataReader missed data.

  • on_requested_incompatible_qos(): The DataReader has found a DataWriter that matches the Topic and has a common partition, but with a QoS that is incompatible with the one defined on the DataReader.

  • on_liveliness_changed(): The liveliness status of a matched DataWriter has changed. Either a DataWriter that was inactive has become active or the other way around.

  • on_sample_rejected(): A received data sample was rejected. See SampleRejectedStatus for further information.

  • on_sample_lost(): A data sample was lost and will never be received. See SampleLostStatus for further information.

Important

For more information about callbacks and its hierarchy, please refer to Listener.

class CustomDataReaderListener : public DataReaderListener
{

public:

    CustomDataReaderListener()
        : DataReaderListener()
    {
    }

    virtual ~CustomDataReaderListener()
    {
    }

    void on_data_available(
            DataReader* reader) override
    {
        static_cast<void>(reader);
        std::cout << "Received new data message" << std::endl;
    }

    void on_subscription_matched(
            DataReader* reader,
            const SubscriptionMatchedStatus& info) override
    {
        static_cast<void>(reader);
        if (info.current_count_change == 1)
        {
            std::cout << "Matched a remote DataWriter" << std::endl;
        }
        else if (info.current_count_change == -1)
        {
            std::cout << "Unmatched a remote DataWriter" << std::endl;
        }
    }

    void on_requested_deadline_missed(
            DataReader* reader,
            const RequestedDeadlineMissedStatus& info) override
    {
        static_cast<void>(reader);
        static_cast<void>(info);
        std::cout << "Some data was not received on time" << std::endl;
    }

    void on_liveliness_changed(
            DataReader* reader,
            const LivelinessChangedStatus& info) override
    {
        static_cast<void>(reader);
        if (info.alive_count_change == 1)
        {
            std::cout << "A matched DataWriter has become active" << std::endl;
        }
        else if (info.not_alive_count_change == 1)
        {
            std::cout << "A matched DataWriter has become inactive" << std::endl;
        }
    }

    void on_sample_rejected(
            DataReader* reader,
            const SampleRejectedStatus& info) override
    {
        static_cast<void>(reader);
        static_cast<void>(info);
        std::cout << "A received data sample was rejected" << std::endl;
    }

    void on_requested_incompatible_qos(
            DataReader* reader,
            const RequestedIncompatibleQosStatus& info) override
    {
        std::cout << "Found a remote Topic with incompatible QoS (QoS ID: " << info.last_policy_id <<
            ")" << std::endl;
    }

    void on_sample_lost(
            DataReader* reader,
            const SampleLostStatus& info) override
    {
        static_cast<void>(reader);
        static_cast<void>(info);
        std::cout << "A data sample was lost and will not be received" << std::endl;
    }

};

3.4.6. Creating a DataReader

A DataReader always belongs to a Subscriber. Creation of a DataReader is done with the create_datareader() member function on the Subscriber instance, that acts as a factory for the DataReader.

Mandatory arguments are:

  • A Topic bound to the data type that will be transmitted.

  • The DataReaderQos describing the behavior of the DataReader. If the provided value is DATAREADER_QOS_DEFAULT, the value of the Default DataReaderQos is used. If the provided value is DATAREADER_QOS_USE_TOPIC_QOS, the values of the default QoS and the provided TopicQoS are used, whereby any policy that is set on the TopicQoS overrides the corresponding policy on the default QoS.

Optional arguments are:

  • A Listener derived from DataReaderListener, implementing the callbacks that will be triggered in response to events and state changes on the DataReader. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the DataReaderListener. By default all events are enabled.

create_datareader() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

// Create a DataReader with default DataReaderQos and no Listener
// The value DATAREADER_QOS_DEFAULT is used to denote the default QoS.
DataReader* data_reader_with_default_qos =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader_with_default_qos)
{
    // Error
    return;
}

// A custom DataReaderQos can be provided to the creation method
DataReaderQos custom_qos;

// Modify QoS attributes
// (...)

DataReader* data_reader_with_custom_qos =
        subscriber->create_datareader(topic, custom_qos);
if (nullptr == data_reader_with_custom_qos)
{
    // Error
    return;
}

// Create a DataReader with default QoS and a custom Listener.
// CustomDataReaderListener inherits from DataReaderListener.
// The value DATAREADER_QOS_DEFAULT is used to denote the default QoS.
CustomDataReaderListener custom_listener;
DataReader* data_reader_with_default_qos_and_custom_listener =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT, &custom_listener);
if (nullptr == data_reader_with_default_qos_and_custom_listener)
{
    // Error
    return;
}

// Create a DataReader with default QoS and a custom TopicQos.
// The value DATAREADER_QOS_USE_TOPIC_QOS is used to denote the default QoS
// and to override the TopicQos.
Topic* topic;
DataReader* data_reader_with_default_qos_and_custom_topic_qos =
        subscriber->create_datareader(topic, DATAREADER_QOS_USE_TOPIC_QOS);
if (nullptr == data_reader_with_default_qos_and_custom_topic_qos)
{
    // Error
    return;
}
3.4.6.1. Profile based creation of a DataReader

Instead of using a DataReaderQos, the name of a profile can be used to create a DataReader with the create_datareader_with_profile() member function on the Subscriber instance.

Mandatory arguments are:

  • A Topic bound to the data type that will be transmitted.

  • A string with the name that identifies the DataReader.

Optional arguments are:

  • A Listener derived from DataReaderListener, implementing the callbacks that will be triggered in response to events and state changes on the DataReader. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the DataReaderListener. By default all events are enabled.

create_datareader_with_profile() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

Note

XML profiles must have been loaded previously. See Loading profiles from an XML file.

// First load the XML with the profiles
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");

// Create a DataReader using a profile and no Listener
DataReader* data_reader_with_profile =
        subscriber->create_datareader_with_profile(topic, "data_reader_profile");
if (nullptr == data_reader_with_profile)
{
    // Error
    return;
}

// Create a DataReader using a profile and a custom Listener.
// CustomDataReaderListener inherits from DataReaderListener.
CustomDataReaderListener custom_listener;
DataReader* data_reader_with_profile_and_custom_listener =
        subscriber->create_datareader_with_profile(topic, "data_reader_profile", &custom_listener);
if (nullptr == data_reader_with_profile_and_custom_listener)
{
    // Error
    return;
}
3.4.6.2. Creating a DataWriter with a custom PayloadPool

A custom PayloadPool can be passed as an argument during the creation of a DataReader. This allows for customizing the management of the information exchanged between DataWriters and DataReaders. The same configuration can be set in the opposite endpoint.

// A DataReaderQos must be provided to the creation method
DataReaderQos qos;

// Create PayloadPool
std::shared_ptr<CustomPayloadPool> payload_pool = std::make_shared<CustomPayloadPool>();

DataReader* data_reader = subscriber->create_datareader(topic, qos, nullptr, StatusMask::all(), payload_pool);
if (nullptr == data_reader)
{
    // Error
    return;
}

This configuration can be performed also in the RTPS layer. The customization example applies both layers.

3.4.6.3. Deleting a DataReader

A DataReader can be deleted with the delete_datareader() member function on the Subscriber instance where the DataReader was created.

Note

A DataReader can only be deleted if all Entities belonging to the DataReader (QueryConditions) have already been deleted. Otherwise, the function will issue an error and the DataReader will not be deleted. This can be performed by using the delete_contained_entities() member function of the DataReader.

// Create a DataReader
DataReader* data_reader =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader)
{
    // Error
    return;
}

// Use the DataReader to communicate
// (...)

// Delete the entities the DataReader created
if (data_reader->delete_contained_entities() != RETCODE_OK)
{
    // DataReader failed to delete the entities it created.
    return;
}

// Delete the DataReader
if (subscriber->delete_datareader(data_reader) != RETCODE_OK)
{
    // Error
    return;
}

3.4.7. SampleInfo

When a sample is retrieved from the DataReader, in addition to the sample data, a SampleInfo instance is returned. This object contains additional information that complements the returned data value and helps on its interpretation. For example, if the valid_data value is false, the DataReader is not informing the application about a new value in the data instance, but a change on its status, and the returned data value must be discarded.

Please, refer to the section Accessing received data for more information regarding how received data can be accessed on the DataReader.

The following sections describe the data members of SampleInfo and the meaning of each one in relation to the returned sample data.

3.4.7.1. sample_state

sample_state indicates whether or not the corresponding data sample has already been read previously. It can take one of these values:

  • READ: This is the first time this data sample has been retrieved.

  • NOT_READ: The data sample has already been read or taken previously.

3.4.7.2. view_state

view_state indicates whether or not this is the very first sample of this data instance that the DataReader retrieves. It can take one of these values:

  • NEW: This is the first time a sample of this instance is retrieved.

  • NOT_NEW: Other samples of this instance have been retrieved previously.

3.4.7.3. instance_state

instance_state indicates whether the instance is currently in existence or it has been disposed. In the latter case, it also provides information about the reason for the disposal. It can take one of these values:

  • ALIVE: The instance is currently in existence.

  • NOT_ALIVE_DISPOSED: A remote DataWriter disposed the instance.

  • NOT_ALIVE_NO_WRITERS: The DataReader disposed the instance because no remote DataWriter that was publishing the instance is alive.

3.4.7.4. disposed_generation_count

disposed_generation_count indicates the number of times the instance had become alive after it was disposed.

3.4.7.5. no_writers_generation_count

no_writers_generation_count indicates the number of times the instance had become alive after it was disposed as NOT_ALIVE_NO_WRITERS.

3.4.7.6. sample_rank

sample_rank indicates the number of samples of the same instance that have been received after this one. For example, a value of 5 means that there are 5 newer samples available on the DataReader.

Note

Currently the sample_rank is not implemented, and its value is always set to 0. It will be implemented on a future release of Fast DDS.

3.4.7.7. generation_rank

generation_rank indicates the number of times the instance was disposed and become alive again between the time the sample was received and the time the most recent sample of the same instance that is still held in the collection was received.

Note

Currently the generation_rank is not implemented, and its value is always set to 0. It will be implemented on a future release of Fast DDS.

3.4.7.8. absolute_generation_rank

absolute_generation_rank indicates the number of times the instance was disposed and become alive again between the time the sample was received and the time the most recent sample of the same instance (which may not be in the collection) was received.

Note

Currently the absolute_generation_rank is not implemented, and its value is always set to 0. It will be implemented on a future release of Fast DDS.

3.4.7.9. source_timestamp

source_timestamp holds the time stamp provided by the DataWriter when the sample was published.

3.4.7.10. instance_handle

instance_handle handles of the local instance.

3.4.7.11. publication_handle

publication_handle handles of the DataWriter that published the data change.

3.4.7.12. valid_data

valid_data is a boolean that indicates whether the data sample contains a change in the value or not. Samples with this value set to false are used to communicate a change in the instance status, e.g., a change in the liveliness of the instance. In this case, the data sample should be dismissed as all the relevant information is in the data members of SampleInfo.

3.4.7.13. sample_identity

sample_identity is an extension for requester-replier configuration. It contains the DataWriter and the sequence number of the current message, and it is used by the replier to fill the related_sample_identity when it sends the reply.

3.4.8. Accessing received data

The application can access and consume the data values received on the DataReader by reading or taking.

When there is no data in the DataReader matching the required conditions, all the operations will return NO_DATA and output parameter will remain unchanged.

In addition to the data values, the data access operations also provide SampleInfo instances with additional information that help interpreting the returned data values, like the originating DataWriter or the publication time stamp. Please, refer to the SampleInfo section for an extensive description of its contents.

3.4.8.1. Loaning and Returning Data and SampleInfo Sequences

The DataReader::read() and DataReader::take() operations (and their variants) return information to the application in two sequences:

  • Received DDS data samples in a sequence of the data type

  • Corresponding information about each DDS sample in a SampleInfo sequence

These sequences are parameters that are passed by the application code into the DataReader::read() and DataReader::take() operations. When the passed sequences are empty (they are initialized but have a maximum length of 0), the middleware will fill those sequences with memory directly loaned from the receive queue itself. There is no copying of the data or SampleInfo when the contents of the sequences are loaned. This is certainly the most efficient way for the application code to retrieve the data.

When doing so, however, the code must return the loaned sequences back to the middleware, so that they can be reused by the receive queue. If the application does not return the loan by calling the DataReader::return_loan() operation, then Fast DDS will eventually run out of memory to store DDS data samples received from the network for that DataReader. See the code below for an example of borrowing and returning loaned sequences.

    // Sequences are automatically initialized to be empty (maximum == 0)
    FooSeq data_seq;
    SampleInfoSeq info_seq;

    // with empty sequences, a take() or read() will return loaned
    // sequence elements
    ReturnCode_t ret_code = data_reader->take(data_seq, info_seq,
                    LENGTH_UNLIMITED, ANY_SAMPLE_STATE,
                    ANY_VIEW_STATE, ANY_INSTANCE_STATE);

    // process the returned data

    // must return the loaned sequences when done processing
    data_reader->return_loan(data_seq, info_seq);
3.4.8.2. Processing returned data

After calling the DataReader::read() or DataReader::take() operations, accessing the data on the returned sequences is quite easy. The sequences API provides a length() operation returning the number of elements in the collections. The application code just needs to check this value and use the [] operator to access the corresponding elements. Elements on the DDS data sequence should only be accessed when the corresponding element on the SampleInfo sequence indicate that valid data is present. When using Data Sharing, it is also important to check that the sample is valid (i.e, not replaced, refer to DataReader and DataWriter history coupling for further information in this regard).

    // Sequences are automatically initialized to be empty (maximum == 0)
    FooSeq data_seq;
    SampleInfoSeq info_seq;

    // with empty sequences, a take() or read() will return loaned
    // sequence elements
    ReturnCode_t ret_code = data_reader->take(data_seq, info_seq,
                    LENGTH_UNLIMITED, ANY_SAMPLE_STATE,
                    ANY_VIEW_STATE, ANY_INSTANCE_STATE);

    // process the returned data
    if (ret_code == RETCODE_OK)
    {
        // Both info_seq.length() and data_seq.length() will have the number of samples returned
        for (FooSeq::size_type n = 0; n < info_seq.length(); ++n)
        {
            // Only samples with valid data should be accessed
            if (info_seq[n].valid_data && data_reader->is_sample_valid(&data_seq[n], &info_seq[n]))
            {
                // Do something with data_seq[n]
            }
        }

        // must return the loaned sequences when done processing
        data_reader->return_loan(data_seq, info_seq);
    }
3.4.8.3. Accessing data on callbacks

When the DataReader receives new data values from any matching DataWriter, it informs the application through two Listener callbacks:

These callbacks can be used to retrieve the newly arrived data, as in the following example.

class CustomizedDataReaderListener : public DataReaderListener
{

public:

    CustomizedDataReaderListener()
        : DataReaderListener()
    {
    }

    virtual ~CustomizedDataReaderListener()
    {
    }

    void on_data_available(
            DataReader* reader) override
    {
        // Create a data and SampleInfo instance
        Foo data;
        SampleInfo info;

        // Keep taking data until there is nothing to take
        while (reader->take_next_sample(&data, &info) == RETCODE_OK)
        {
            if (info.valid_data)
            {
                // Do something with the data
                std::cout << "Received new data value for topic "
                          << reader->get_topicdescription()->get_name()
                          << std::endl;
            }
            else
            {
                std::cout << "Remote writer for topic "
                          << reader->get_topicdescription()->get_name()
                          << " is dead" << std::endl;
            }
        }
    }

};

Note

If several new data changes are received at once, the callbacks may be triggered just once, instead of once per change. The application must keep reading or taking until no new changes are available.

3.4.8.4. Accessing data with a waiting thread
3.4.8.4.1. Wait-sets and DataAvailable status condition

Instead of relying on the Listener to try and get new data values, the application can also dedicate a thread to wait until any new data is available on the DataReader. This can be done using a wait-set to wait for a change on the DataAvailable status.

// Create a DataReader
DataReader* data_reader =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader)
{
    // Error
    return;
}

// Prepare a wait-set to wait for data on the DataReader
WaitSet wait_set;
StatusCondition& condition = data_reader->get_statuscondition();
condition.set_enabled_statuses(StatusMask::data_available());
wait_set.attach_condition(condition);

// Create a data and SampleInfo instance
Foo data;
SampleInfo info;

//Define a timeout of 5 seconds
eprosima::fastdds::dds::Duration_t timeout (5, 0);

// Loop reading data as it arrives
// This will make the current thread to be dedicated exclusively to
// waiting and reading data until the remote DataWriter dies
while (true)
{
    ConditionSeq active_conditions;
    if (RETCODE_OK == wait_set.wait(active_conditions, timeout))
    {
        while (RETCODE_OK == data_reader->take_next_sample(&data, &info))
        {
            if (info.valid_data)
            {
                // Do something with the data
                std::cout << "Received new data value for topic "
                          << topic->get_name()
                          << std::endl;
            }
            else
            {
                // If the remote writer is not alive, we exit the reading loop
                std::cout << "Remote writer for topic "
                          << topic->get_name()
                          << " is dead" << std::endl;
                break;
            }
        }
    }
    else
    {
        std::cout << "No data this time" << std::endl;
    }
}
3.4.8.4.2. DataReader non-blocking calls

The same could be achieved using the DataReader::wait_for_unread_message() member function, that blocks until a new data sample is available or the given timeout expires. If no new data was available after the timeout expired, it will return with value false. This function returning with value true means there is new data available on the DataReader ready for the application to retrieve.

// Create a DataReader
DataReader* data_reader =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader)
{
    // Error
    return;
}

// Create a data and SampleInfo instance
Foo data;
SampleInfo info;

//Define a timeout of 5 seconds
eprosima::fastdds::dds::Duration_t timeout (5, 0);

// Loop reading data as it arrives
// This will make the current thread to be dedicated exclusively to
// waiting and reading data until the remote DataWriter dies
while (true)
{
    if (data_reader->wait_for_unread_message(timeout))
    {
        if (RETCODE_OK == data_reader->take_next_sample(&data, &info))
        {
            if (info.valid_data)
            {
                // Do something with the data
                std::cout << "Received new data value for topic "
                          << topic->get_name()
                          << std::endl;
            }
            else
            {
                // If the remote writer is not alive, we exit the reading loop
                std::cout << "Remote writer for topic "
                          << topic->get_name()
                          << " is dead" << std::endl;
                break;
            }
        }
    }
    else
    {
        std::cout << "No data this time" << std::endl;
    }
}

3.5. Topic

A Topic conceptually fits between publications and subscriptions. Each publication channel must be unambiguously identified by the subscriptions in order to receive only the data flow they are interested in, and not data from other publications. A Topic serves this purpose, allowing publications and subscriptions that share the same Topic to match and start communicating. In that sense, the Topic acts as a description for a data flow.

Publications are always linked to a single Topic, while subscriptions are linked to a broader concept of TopicDescription.

_images/topic_class_diagram.svg

Topic class diagram

3.5.1. Topics, keys and instances

By definition, a Topic is linked to a single data type, so each data sample related to a Topic could be understood as an update on the information described by the data type. However, it is possible to include a logical separation and have, within the same Topic, several instances referring to the same data type. Thus, the received data sample will be an update for a specific instance of that Topic. Therefore, a Topic identifies data of a single type, ranging from one single instance to a whole collection of instances of that given type, as shown in the figure below.

_images/instances.png

The different instances gathered under the same topic are distinguishable by means of one or more data fields that form the key to that data set. The key description has to be indicated to the middleware. The rule is simple: different data values with the same key value represent successive data samples for the same instance, while different data values with different keys represent different topic instances. If no key is provided, the data set associated with the Topic is restricted to a single instance. Please refer to Data types with a key for more information about how to set the key in eProsima Fast DDS.

3.5.1.1. Instance advantages

The advantage of using instances instead of creating a new DataWriter, DataReader, and Topic is that the corresponding entity is already created and discovered. Consequently, there is less memory usage, and no new discovery (with the related metatraffic involved as explained in Discovery) is necessary. Another advantage is that several QoS are applied per topic instance; e.g. the HistoryQosPolicy is kept for each instance in the DataWriter. Thus, instances could be tuned to a wide range of applications.

3.5.1.2. Instance lifecycle

When reading or taking data from the DataReader (as explained in Accessing received data), a SampleInfo is also returned. This SampleInfo provides additional information about the instance lifecycle, specifically with the view_state, instance_state, disposed_generation_count, and no_writers_generation_count. The diagram below shows the statechart of instance_state and view_state for a single instance.

_images/instance-lifecycle.png
3.5.1.3. Practical applications

This section provides a couple of examples to help clarify the use of DDS instances.

3.5.1.3.1. Commercial flights tracking

Airspace and the air traffic going through it are typically managed by the air traffic controllers that are in charge of organizing the air traffic, preventing collisions, and providing information. In this scenario, each air traffic control center takes responsibility for a specific flight area and delivers the data to the airspace traffic management system, which unifies the flight information.

Any time an air traffic control center discovers a plane coming into its controlled flight zone, tracking information about that specific flight is notified to the airspace traffic management center. Such a flow of information could be implemented by means of DDS by creating a specific Topic where the information related to the flight location is published. In that case, the management center would be required to create, if not existing previously, the corresponding Topic and DataReader to have access to the flight information, with the corresponding memory consumption and discovery metatraffic required. On the other hand, a cleverer implementation could leverage topic instances to relay the information from the local air traffic control centers to the airspace traffic management center. The topic instances might be identified using the airline name and the flight number (i.e. IBERIA 1234) as Topic instance key. The sample data being relayed would be the location of each flight being tracked at any given time. The following IDL defines the data described model:

struct FlightPosition
{
    // Unique ID: airline name
    @key string<256> airline_name;

    // Unique ID: flight number
    @key short flight_number;

    // Coordinates
    double latitude;
    double longitude;
    double altitude;
};

Once a new flight is discovered by a control center, the corresponding instance is registered into the system:

// Create data sample
FlightPosition first_flight_position;

// Specify the flight instance
first_flight_position.airline_name("IBERIA");
first_flight_position.flight_number(1234);

// Register instance
eprosima::fastdds::rtps::InstanceHandle_t first_flight_handle =
        data_writer->register_instance(&first_flight_position);

register_instance() returns an InstanceHandle_t which can be used to efficiently call the next operations (i.e. write(), dispose(), or unregister_instance()) over the instance. The returned InstanceHandle_t contains the instance keyhash so it does not have to be recalculated again from the data sample. In case of following this approach, the application must take charge of mapping the instance handles to the corresponding instances.

// Update position value received from the plane
first_flight_position.latitude(39.08);
first_flight_position.longitude(-84.21);
first_flight_position.altitude(1500);

// Write sample to the instance
data_writer->write(&first_flight_position, first_flight_handle);

On the other hand, the user application could directly call the DataWriter instance operations with a NIL instance handle. In this case, the instance handle would be calculated every time an operation is done over the instance, which can be time consuming depending on the specific data type being used.

// New data sample
FlightPosition second_flight_position;

// New instance
second_flight_position.airline_name("RYANAIR");
second_flight_position.flight_number(4321);

// Update plane location
second_flight_position.latitude(40.02);
second_flight_position.longitude(-84.32);
second_flight_position.altitude(5000);

// Write sample directly without registering the instance
data_writer->write(&second_flight_position);

Warning

The correct management of the instance handles in the user application is paramount. Otherwise, a sample corresponding to a different instance could wrongly update the instance which handle the user has passed to the operation (if a non NIL instance is provided, the instance handle is not recalculated, trusting that the one passed by the user is the correct one). The following code updates the first instance of this example with the information coming from the second instance.

data_writer->write(&second_flight_position, first_flight_handle);

Once the plane leaves the controlled area, the air traffic control center may unregister the instance. Unregistering implies that the DataWriter for this specific center has no more information about the unregistered instance, and in this way the matched DataReaders in the management center are notified. The flight is still in the air but out of scope of this particular DataWriter. The instance is alive but no longer tracked by this center.

data_writer->unregister_instance(&first_flight_position, first_flight_handle);
data_writer->unregister_instance(&second_flight_position, HANDLE_NIL);

Finally, when the flight lands, the instance may be disposed. This means, in this specific example, that as far as the DataWriter knows, the instance no longer exists and should be considered not alive. With this operation, the DataWriter conveys this information to the matched DataReaders.

data_writer->dispose(&first_flight_position, first_flight_handle);
data_writer->dispose(&second_flight_position, HANDLE_NIL);

From the management center point of view, the samples are read using the same DataReader subscribed to the Topic where the instances are being published. However, valid_data must be checked to ensure that the sample received contains a data sample. Otherwise, a change of the instance state is being notified. Instance lifecycle contains a diagram showing the instance statechart.

if (RETCODE_OK == data_reader->take_next_sample(&data, &info))
{
    if (info.valid_data)
    {
        // Data sample has been received
    }
    else if (info.instance_state == NOT_ALIVE_DISPOSED_INSTANCE_STATE)
    {
        // A remote DataWriter has disposed the instance
    }
    else if (info.instance_state == NOT_ALIVE_NO_WRITERS_INSTANCE_STATE)
    {
        // None of the matched DataWriters are writing in the instance.
        // The instance can be safely disposed.
    }
}
3.5.1.3.2. Relational databases

Consider now that the air traffic management center wants to keep a database with the flights being tracked. Using DDS instances, maintaining a relational database is almost direct. The instance key (unique identifier of the instance) is analogous to the primary key of the database. Thus, the airspace traffic management center can keep the latest update for each instance in a table like the one below:

Instance handle [PK]

Data

1

Position1

2

Position2

3

Position3

4

Position4

5

Position5

In this case, every time a new sample is received, the corresponding instance entry in the database will be updated with the latest known location. Disposing the instance may translate in erasing the corresponding data from the database. In this scenario, registering and unregistering the instances does not reflect in the database, although if the instance_state and view_state are also persisted, then the instance lifecycle could be tracked as well. A DataWriter communicating that it is going to be publishing data about a specific instance is of no interest to the database until a new data is received and then an insert is directly done with the new discovered instance.

Historical data can also be stored in the relational database, even though depending on the use case, a time series database might be considered to improve efficiency. In the scenario being considered, the sample timestamp could be used, besides the instance handle, as primary key to be able to access the historical tracking data of an specific flight.

Instance handle [PK]

Source Timestamp [PK]

Data

1

1

Position1

2

1

Position2

1

2

Position3

1

3

Position4

2

2

Position5

In this case, looking for a specific instance handle would return the flight tracking information:

Instance handle [Fixed]

Source Timestamp

Data

1

1

Position1

1

2

Position3

1

3

Position4

Whereas looking for a specific timestamp would allow to have a picture of the different flight locations at a specific time:

Instance handle

Source Timestamp [Fixed]

Data

1

2

Position3

2

2

Position5

3.5.2. TopicDescription

TopicDescription is an abstract class that serves as the base for all classes describing a data flow. Applications will not create instances of TopicDescription directly, they must create instances of one of its specializations instead. At the moment, the only specializations implemented are Topic, and ContentFilteredTopic.

3.5.3. Topic

A Topic is a specialization of the broader concept of TopicDescription. A Topic represents a single data flow between Publisher and Subscriber, providing:

  • The name to identify the data flow.

  • The data type that is transmitted on that flow.

  • The QoS values related to the data itself.

The behavior of the Topic can be modified with the QoS values specified on TopicQos. The QoS values can be set at the creation of the Topic, or modified later with the Topic::set_qos() member function.

Like other Entities, Topic accepts a Listener that will be notified of status changes on the Topic.

Please refer to Creating a Topic for more information about how to create a Topic.

3.5.3.1. TopicQos

TopicQos controls the behavior of the Topic. Internally it contains the following QosPolicy objects:

Refer to the detailed description of each QosPolicy-api class for more information about their usage and default values.

The QoS value of a previously created Topic can be modified using the Topic::set_qos() member function.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Topic with default TopicQos
Topic* topic =
        participant->create_topic("TopicName", "DataTypeName", TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
TopicQos qos = topic->get_qos();

// Modify QoS attributes
// (...)

// Assign the new Qos to the object
topic->set_qos(qos);
3.5.3.1.1. Default TopicQos

The default TopicQos refers to the value returned by the get_default_topic_qos() member function on the DomainParticipant instance. The special value TOPIC_QOS_DEFAULT can be used as QoS argument on create_topic() or Topic::set_qos() member functions to indicate that the current default TopicQos should be used.

When the system starts, the default TopicQos is equivalent to the default constructed value TopicQos(). The default TopicQos can be modified at any time using the get_default_topic_qos() member function on the DomainParticipant instance. Modifying the default TopicQos will not affect already existing Topic instances.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
TopicQos qos_type1 = participant->get_default_topic_qos();

// Modify QoS attributes
// (...)

// Set as the new default TopicQos
if (participant->set_default_topic_qos(qos_type1) != RETCODE_OK)
{
    // Error
    return;
}

// Create a Topic with the new default TopicQos.
Topic* topic_with_qos_type1 =
        participant->create_topic("TopicName", "DataTypeName", TOPIC_QOS_DEFAULT);
if (nullptr == topic_with_qos_type1)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
TopicQos qos_type2;

// Modify QoS attributes
// (...)

// Set as the new default TopicQos
if (participant->set_default_topic_qos(qos_type2) != RETCODE_OK)
{
    // Error
    return;
}

// Create a Topic with the new default TopicQos.
Topic* topic_with_qos_type2 =
        participant->create_topic("TopicName", "DataTypeName", TOPIC_QOS_DEFAULT);
if (nullptr == topic_with_qos_type2)
{
    // Error
    return;
}

// Resetting the default TopicQos to the original default constructed values
if (participant->set_default_topic_qos(TOPIC_QOS_DEFAULT)
        != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following
if (participant->set_default_topic_qos(TopicQos())
        != RETCODE_OK)
{
    // Error
    return;
}

get_default_topic_qos() member function also accepts the value TOPIC_QOS_DEFAULT as input argument. This will reset the current default TopicQos to default constructed value TopicQos().

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a custom TopicQos
TopicQos custom_qos;

// Modify QoS attributes
// (...)

// Create a topic with a custom TopicQos
Topic* topic = participant->create_topic("TopicName", "DataTypeName", custom_qos);
if (nullptr == topic)
{
    // Error
    return;
}

// Set the QoS on the topic to the default
if (topic->set_qos(TOPIC_QOS_DEFAULT) != RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following:
if (topic->set_qos(participant->get_default_topic_qos())
        != RETCODE_OK)
{
    // Error
    return;
}

Note

The value TOPIC_QOS_DEFAULT has different meaning depending on where it is used:

3.5.4. ContentFilteredTopic

A ContentFilteredTopic is a specialization of the broader concept of TopicDescription. A ContentFilteredTopic is a Topic with filtering properties. It makes it possible to subscribe to a Topic while at the same time specify interest on a subset of the Topic’s data.

Important

Note that a ContentFilteredTopic can only be used to create a DataReader, not a DataWriter.

A ContentFilteredTopic provides a relationship between a Topic, called the related topic, and some user-defined filtering properties:

  • A filter expression, which establishes a logical expression on the content of the related topic. It is similar to the WHERE clause in a SQL statement.

  • A list of expression parameters, which give values to the parameters present in the filter expression. There must be one parameter string for each parameter in the filter expression.

Note that a ContentFilteredTopic is not an Entity, and thus it has neither QoS nor listener. A DataReader created with a ContentFilteredTopic will use the QoS from the related topic. Multiple DataReaders can be created for the same ContentFilteredTopic, and changing the filter properties of a ContentFilteredTopic will affect all DataReaders using it.

Please refer to Filtering data on a Topic and Where is filtering applied: writer vs reader side for more information about how to use ContentFilteredTopic.

3.5.5. TopicListener

TopicListener is an abstract class defining the callbacks that will be triggered in response to state changes on the Topic. By default, all these callbacks are empty and do nothing. The user should implement a specialization of this class overriding the callbacks that are needed on the application. Callbacks that are not overridden will maintain their empty implementation.

TopicListener has the following callback:

  • on_inconsistent_topic(): A remote Topic is discovered with the same name but different characteristics as another locally created Topic.

Warning

Currently on_inconsistent_topic() is not implemented (it will never be called), and will be implemented on a future release of Fast DDS.

class CustomTopicListener : public TopicListener
{

public:

    CustomTopicListener()
        : TopicListener()
    {
    }

    virtual ~CustomTopicListener()
    {
    }

    void on_inconsistent_topic(
            Topic* topic,
            InconsistentTopicStatus status) override
    {
        static_cast<void>(topic);
        static_cast<void>(status);
        std::cout << "Inconsistent topic received discovered" << std::endl;
    }

};

3.5.6. Definition of data types

The definition of the data type exchanged in a Topic is divided in two classes: the TypeSupport and the TopicDataType.

TopicDataType describes the data type exchanged between a publication and a subscription, i.e., the data corresponding to a Topic. The user has to create a specialized class for each specific type that will be used by the application.

Any specialization of TopicDataType must be registered in the DomainParticipant before it can be used to create Topic objects. A TypeSupport object encapsulates an instance of TopicDataType, providing the functions needed to register the type and interact with the publication and subscription. To register the data type, create a new TypeSupport with a TopicDataType instance and use the register_type() member function on the TypeSupport. Then the Topic can be created with the registered type name.

Note

Registering two different data types on the same DomainParticipant with identical names is not allowed and will issue an error. However, it is allowed to register the same data type within the same DomainParticipant, with the same or different names. If the same data type is registered twice on the same DomainParticipant with the same name, the second registering will have no effect, but will not issue any error.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Register the data type in the DomainParticipant.
// If nullptr is used as name argument, the one returned by the type itself is used
TypeSupport custom_type_support(new CustomDataType());
custom_type_support.register_type(participant, nullptr);

// The previous instruction is equivalent to the following one
// Even if we are registering the same data type with the same name twice, no error will be issued
custom_type_support.register_type(participant, custom_type_support.get_type_name());

// Create a Topic with the registered type.
Topic* topic =
        participant->create_topic("topic_name", custom_type_support.get_type_name(), TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Create an alias for the same data type using a different name.
custom_type_support.register_type(participant, "data_type_name");

// We can now use the aliased name to If no name is given, it uses the name returned by the type itself
Topic* another_topic =
        participant->create_topic("other_topic_name", "data_type_name", TOPIC_QOS_DEFAULT);
if (nullptr == another_topic)
{
    // Error
    return;
}
3.5.6.1. Dynamic data types

Instead of directly writing the specialized TopicDataType class, it is possible to dynamically define data types following the OMG Extensible and Dynamic Topic Types for DDS interface. Data types can also be described on an XML file that is dynamically loaded.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Load the XML file with the type description
DomainParticipantFactory::get_instance()->load_XML_profiles_file("example_type.xml");

// Retrieve the an instance of the desired type
DynamicTypeBuilder::_ref_type dyn_type_builder;
DomainParticipantFactory::get_instance()->get_dynamic_type_builder_from_xml_by_name("DynamicType",
        dyn_type_builder);

// Register dynamic type
TypeSupport dyn_type_support(new DynamicPubSubType(dyn_type_builder->build()));
dyn_type_support.register_type(participant, nullptr);

// Create a Topic with the registered type.
Topic* topic =
        participant->create_topic("topic_name", dyn_type_support.get_type_name(), TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

A complete description of the dynamic definition of types can be found on the XTypes section.

3.5.6.2. Data types with a key

Data types that define a set of fields to form a unique key can distinguish different data sets within the same data type.

To define a keyed Topic, the getKey() member function on the TopicDataType has to be overridden to return the appropriate key value according to the data fields. Additionally, the m_isGetKeyDefined data member needs to be set to true to let the entities know that this is a keyed Topic and that getKey() should be used. Types that do not define a key will have m_isGetKeyDefined set to false.

There are three ways to implement keys on the TopicDataType:

  • Adding a @Key annotation to the members that form the key in the IDL file when using Fast DDS-Gen.

  • Adding the attribute Key to the member and its parents when using XTypes.

  • Manually implementing the getKey() member function on the TopicDataType and setting the m_isGetKeyDefined data member value to true.

Data types with key are used to define data sub flows on a single Topic. Data values with the same key on the same Topic represent data from the same sub-flow, while data values with different keys on the same Topic represent data from different sub-flows. The middleware keeps these sub-flows separated, but all will be restricted to the same QoS values of the Topic. If no key is provided, the data set associated with the Topic is restricted to a single flow.

3.5.7. Creating a Topic

A Topic always belongs to a DomainParticipant. Creation of a Topic is done with the create_topic() member function on the DomainParticipant instance, that acts as a factory for the Topic.

Mandatory arguments are:

  • A string with the name that identifies the Topic.

  • The name of the registered data type that will be transmitted.

  • The TopicQos describing the behavior of the Topic. If the provided value is TOPIC_QOS_DEFAULT, the value of the Default TopicQos is used.

Optional arguments are:

  • A Listener derived from TopicListener, implementing the callbacks that will be triggered in response to events and state changes on the Topic. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the TopicListener. By default all events are enabled.

create_topic() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Topic with default TopicQos and no Listener
// The symbol TOPIC_QOS_DEFAULT is used to denote the default QoS.
Topic* topic_with_default_qos =
        participant->create_topic("TopicName", "DataTypeName", TOPIC_QOS_DEFAULT);
if (nullptr == topic_with_default_qos)
{
    // Error
    return;
}

// A custom TopicQos can be provided to the creation method
TopicQos custom_qos;

// Modify QoS attributes
// (...)

Topic* topic_with_custom_qos =
        participant->create_topic("TopicName", "DataTypeName", custom_qos);
if (nullptr == topic_with_custom_qos)
{
    // Error
    return;
}

// Create a Topic with default QoS and a custom Listener.
// CustomTopicListener inherits from TopicListener.
// The symbol TOPIC_QOS_DEFAULT is used to denote the default QoS.
CustomTopicListener custom_listener;
Topic* topic_with_default_qos_and_custom_listener =
        participant->create_topic("TopicName", "DataTypeName", TOPIC_QOS_DEFAULT, &custom_listener);
if (nullptr == topic_with_default_qos_and_custom_listener)
{
    // Error
    return;
}
3.5.7.1. Profile based creation of a Topic

Instead of using a TopicQos, the name of a profile can be used to create a Topic with the create_topic_with_profile() member function on the DomainParticipant instance.

Mandatory arguments are:

  • A string with the name that identifies the Topic.

  • The name of the registered data type that will be transmitted.

  • The name of the profile to be applied to the Topic.

Optional arguments are:

  • A Listener derived from TopicListener, implementing the callbacks that will be triggered in response to events and state changes on the Topic. By default empty callbacks are used.

  • A StatusMask that activates or deactivates triggering of individual callbacks on the TopicListener. By default all events are enabled.

create_topic_with_profile() will return a null pointer if there was an error during the operation, e.g. if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer.

Note

XML profiles must have been loaded previously. See Loading profiles from an XML file.

// First load the XML with the profiles
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Topic using a profile and no Listener
Topic* topic_with_profile =
        participant->create_topic_with_profile("TopicName", "DataTypeName", "topic_profile");
if (nullptr == topic_with_profile)
{
    // Error
    return;
}

// Create a Topic using a profile and a custom Listener.
// CustomTopicListener inherits from TopicListener.
CustomTopicListener custom_listener;
Topic* topic_with_profile_and_custom_listener =
        participant->create_topic_with_profile("TopicName", "DataTypeName", "topic_profile", &custom_listener);
if (nullptr == topic_with_profile_and_custom_listener)
{
    // Error
    return;
}
3.5.7.2. Deleting a Topic

A Topic can be deleted with the delete_topic() member function on the DomainParticipant instance where the Topic was created.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Topic
Topic* topic =
        participant->create_topic("TopicName", "DataTypeName", TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Use the Topic to communicate
// (...)

// Delete the Topic
if (participant->delete_topic(topic) != RETCODE_OK)
{
    // Error
    return;
}

3.5.8. Filtering data on a Topic

3.5.8.1. Creating a ContentFilteredTopic

A ContentFilteredTopic always belongs to a DomainParticipant. Creation of a ContentFilteredTopic is done with the create_contentfilteredtopic() member function on the DomainParticipant instance, that acts as a factory for the ContentFilteredTopic.

Mandatory arguments are:

  • A string with the name that identifies the ContentFilteredTopic.

  • The related Topic being filtered.

  • A string with the filter expression indicating the conditions for a sample to be returned.

  • A list of strings with the value of the parameters present on the filter expression.

Note

The number of parameter values cannot exceed the maximum set by the expression_parameters QoS configuration. The default (and absolute) maximum allowed as set by the OMG DDS Standard is 100.

Optional arguments are:

  • A string with the name of the filter class to use for the filter creation. This allows the user to create filters different from the standard SQL like one (please refer to Using custom filters). Defaults to FASTDDS_SQLFILTER_NAME (DDSSQL).

Important

Setting an empty string as filter expression results in the disabling of the filtering. This can be used to enable/disable the DataReader filtering capabilities at any given time by simply updating the filter expression.

create_contentfilteredtopic() will return a null pointer if there was an error during the operation, e.g. if the related Topic belongs to a different DomainParticipant, a Topic with the same name already exists, syntax errors on the filter expression, or missing parameter values. It is advisable to check that the returned value is a valid pointer.

Note

Different filter classes may impose different requirements on the related Topic, the expression, or the parameters. The default filter class, in particular, requires that a TypeObject for the related Topic’s type has been registered. When using fastddsgen the TypeObject registration code is generated by default.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create the Topic.
/* IDL
 *
 * struct HelloWorld
 * {
 *     long index;
 *     string message;
 * }
 *
 */
Topic* topic =
        participant->create_topic("HelloWorldTopic", "HelloWorld", TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Create a ContentFilteredTopic using an expression with no parameters
std::string expression = "message like 'Hello*'";
std::vector<std::string> parameters;
ContentFilteredTopic* filter_topic =
        participant->create_contentfilteredtopic("HelloWorldFilteredTopic1", topic, expression, parameters);
if (nullptr == filter_topic)
{
    // Error
    return;
}

// Create a ContentFilteredTopic using an expression with parameters
expression = "message like %0 or index > %1";
parameters.push_back("'*world*'");
parameters.push_back("20");
ContentFilteredTopic* filter_topic_with_parameters =
        participant->create_contentfilteredtopic("HelloWorldFilteredTopic2", topic, expression, parameters);
if (nullptr == filter_topic_with_parameters)
{
    // Error
    return;
}

// The ContentFilteredTopic instances can then be used to create DataReader objects.
Subscriber* subscriber =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber)
{
    // Error
    return;
}

DataReader* reader_on_filter = subscriber->create_datareader(filter_topic, DATAREADER_QOS_DEFAULT);
if (nullptr == reader_on_filter)
{
    // Error
    return;
}

DataReader* reader_on_filter_with_parameters =
        subscriber->create_datareader(filter_topic_with_parameters, DATAREADER_QOS_DEFAULT);
if (nullptr == reader_on_filter_with_parameters)
{
    // Error
    return;
}
3.5.8.2. Updating the filter expression and parameters

A ContentFilteredTopic provides several member functions for the management of the filter expression and the expression parameters:

// This lambda prints all the information of a ContentFilteredTopic
auto print_filter_info = [](
    const ContentFilteredTopic* filter_topic)
        {
            std::cout << "ContentFilteredTopic info for '" << filter_topic->get_name() << "':" << std::endl;
            std::cout << "  - Related Topic: " << filter_topic->get_related_topic()->get_name() << std::endl;
            std::cout << "  - Expression:    " << filter_topic->get_filter_expression() << std::endl;
            std::cout << "  - Parameters:" << std::endl;

            std::vector<std::string> parameters;
            filter_topic->get_expression_parameters(parameters);
            size_t i = 0;
            for (const std::string& parameter : parameters)
            {
                std::cout << "    " << i++ << ": " << parameter << std::endl;
            }
        };

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Topic
/* IDL
 *
 * struct HelloWorld
 * {
 *     long index;
 *     string message;
 * }
 *
 */
Topic* topic =
        participant->create_topic("HelloWorldTopic", "HelloWorldTopic", TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Create a ContentFilteredTopic
ContentFilteredTopic* filter_topic =
        participant->create_contentfilteredtopic("HelloWorldFilteredTopic", topic, "index > 10", {});
if (nullptr == filter_topic)
{
    // Error
    return;
}

// Print the information
print_filter_info(filter_topic);

// Use the ContentFilteredTopic on DataReader objects.
// (...)

// Update the expression
if (RETCODE_OK !=
        filter_topic->set_filter_expression("message like %0 or index > %1", {"'Hello*'", "15"}))
{
    // Error
    return;
}

// Print the updated information
print_filter_info(filter_topic);

// Update the parameters
if (RETCODE_OK !=
        filter_topic->set_expression_parameters({"'*world*'", "222"}))
{
    // Error
    return;
}

// Print the updated information
print_filter_info(filter_topic);
3.5.8.3. Deleting a ContentFilteredTopic

A ContentFilteredTopic can be deleted with the delete_contentfilteredtopic() member function on the DomainParticipant instance where the ContentFilteredTopic was created.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Topic
/* IDL
 *
 * struct HelloWorld
 * {
 *     long index;
 *     string message;
 * }
 *
 */
Topic* topic =
        participant->create_topic("HelloWorldTopic", "HelloWorldTopic", TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Create a ContentFilteredTopic
ContentFilteredTopic* filter_topic =
        participant->create_contentfilteredtopic("HelloWorldFilteredTopic", topic, "index > 10", {});
if (nullptr == filter_topic)
{
    // Error
    return;
}

// Use the ContentFilteredTopic on DataReader objects.
// (...)

// Delete the ContentFilteredTopic
if (RETCODE_OK != participant->delete_contentfilteredtopic(filter_topic))
{
    // Error
    return;
}

3.5.9. The default SQL-like filter

Filter expressions used by ContentFilteredTopic API may use a subset of SQL syntax, extended with the possibility to use program variables in the SQL expression. This section shows this default SQL-like syntax and how to use it.

3.5.9.1. Grammar

The allowed SQL expressions are defined with the BNF-grammar below.

The following conventions are made:

  • “Terminals” are quoted.

  • TOKENS are typeset in code block with black font color.

Expression          ::= FilterExpression
FilterExpression    ::= Condition
Condition           ::= Predicate |
                        Condition "AND" Condition |
                        Condition "OR" Condition |
                        "NOT" Condition |
                        "(" Condition ")"
Predicate           ::= ComparisonPredicate |
                        BetweenPredicate
ComparisonPredicate ::= FIELDNAME RelOp Parameter |
                        Parameter RelOp FIELDNAME |
                        FIELDNAME RelOp FIELDNAME
BetweenPredicate    ::= FIELDNAME "BETWEEN" Range |
                        FIELDNAME "NOT BETWEEN" Range
RelOp               ::= "=" | ">" | ">=" | "<" | "<=" |
                        "<>" | "!=" | like | match
Range               ::= Parameter "AND" Parameter
Parameter           ::= BOOLEANVALUE |
                        INTEGERVALUE |
                        CHARVALUE |
                        FLOATVALUE |
                        STRINGVALUE |
                        ENUMERATEDVALUE |
                        PARAMETER

“Terminals” and TOKENS are case sensitive but both uppercase and lowercase are supported.

The syntax and meaning of the tokens used in the SQL grammar is described as follows:

  • FIELDNAME: is a reference to a field in the data-structure. The dot . is used to navigate through nested structures. The number of dots that may be used in a FIELDNAME is unlimited. The FIELDNAME can refer to fields at any depth in the data structure. The names of the field are those specified in the IDL definition of the corresponding structure.

    FIELDNAME     ::= FieldNamePart ( "." FieldNamePart )*
    FieldNamePart ::= Identifier ( "[" Integer "]" )?
    

    An example of FIELDNAMEs:

    "points[0] = 0 AND color.red < 100"
    
    struct Color
    {
        octet red;
        octet green;
        octet blue;
    };
    
    struct Shape
    {
        long points[4];
        Color color;
    };
    
  • BOOLEANVALUE: Can either be true of false, case sensitive.

    BOOLEANVALUE ::= ["TRUE", "true", "FALSE", "false"]
    
  • INTEGERVALUE: Any series of digits, optionally preceded by a plus or minus sign, representing a decimal integer value within the range of the system. A hexadecimal number is preceded by 0x and must be a valid hexadecimal expression.

    INTEGERVALUE ::= (["+","-"])? Integer
    Integer      ::= (["0"-"9"])+ | ["0x","0X"](["0"-"9", "A"-"F", "a"-"f"])+
    

    An example of INTEGERVALUE:

    value = -10
    
  • CHARVALUE: A single character enclosed between single quotes.

    CHARVALUE ::= "'" Character "'"
    Character ::= ~["\n"]
    

    An example of CHARVALUE:

    value = 'c'
    
  • FLOATVALUE: Any series of digits, optionally preceded by a plus or minus sign and optionally including a floating point (.). A power-of-ten expression may be postfixed, which has the syntax e:sup:n, where n is a number, optionally preceded by a plus or minus sign.

    FLOATVALUE ::= (["+"], "-"])? (Integer Exponent | Integer Fractional | Integer Fractional Exponent)
    Fractional ::= "." Integer
    Exponent   ::= ["e","E"] (["+"], "-"])? Integer
    

    An example of FLOATVALUE:

    value = 10.1e-10
    
  • STRINGVALUE: Any series of characters encapsulated in single quotes, except a new-line character or a right quote. A string starts with a left or right quote, but ends with a right quote.

    STRINGVALUE ::= ["'"] ~["'", "\r", "\n"] ["'"]
    

    An example of STRINGVALUE:

    value = 'This is a string'
    
  • ENUMERATEDVALUE: An enumerated value is a reference to a value declared within an enumeration. Enumerated values consist of the name of the enumeration label enclosed in single quotes. The name used for the enumeration label must correspond to the label names specified in the IDL definition of the enumeration.

    ENUMERATEDVALUE ::= ["'"] ~["'", "\r", "\n"] ["'"]
    

    An example of ENUMERATEDVALUE:

    value = 'ENUM_VALUE_1'
    
    enum MyEnum
    {
        ENUM_VALUE_1,
        ENUM_VALUE_2,
        ENUM_VALUE_3
    };
    
    struct Enumerators
    {
        MyEnum value;
    };
    
  • PARAMETER: A parameter is of the form %n, where n represents a natural number (zero included) smaller than 100. It refers to the n + 1 th argument in the given context.

    PARAMETER ::= ["%"] ["0"-"9"] (["0"-"9"])?
    

    An example of PARAMETER:

    value = %1
    
3.5.9.2. Like condition

The like operator is similar as the one defined by SQL. This operator can only be used with strings. There are two wildcards that could be used in conjunction with this operator

  • The percent sign % (or its alias *) represents zero, one, or multiple characters.

  • The underscore sign _ (or its alias ?) represents one single character.

All wildcards can also be used in combinations.

An example of like operator

"str like '%bird%'"
struct Like
{
    string str;
};

where string There are birds flying will return true.

3.5.9.3. Match condition

The match operator performs a full-text search using a regular expression. This operator can only be used with strings. It uses the Basic Regular Expression (BRE) defined by POSIX.

An example of match operator

"str match '^The'"
struct Like
{
    string str;
};

where string There are birds flying will return true.

3.5.9.4. Type comparisons

For the supported operators in the grammar, next table shows the type compatibility.

Operator1 | Operator2

BOOLEAN

INTEGER

FLOAT

CHAR

STRING

ENUM

BOOLEAN

INTEGER

FLOAT

CHAR

STRING

ENUM

✅ *

(*) Only for the same enumerated type.

3.5.9.5. Example

Assuming Topic Shape has next IDL definition.

struct Shape
{
    long x,
    long y,
    long z,
    long width,
    long height
};

An example of filter expression would be:

"x < 23 AND y > 50 AND width BETWEEN %0 AND %1"

A ContentFilteredTopic may be created using this filter expression as explained in section Creating a ContentFilteredTopic.

ContentFilteredTopic* sql_filter_topic =
        participant->create_contentfilteredtopic("Shape", topic,
                "x < 23 AND y > 50 AND width BETWEEN %0 AND %1",
                {"10", "20"});

In this example parameters are used. Internally the ContentFilteredTopic will be created with the filter expression below, after setting the provided parameters.

"x < 23 AND y > 50 AND width BETWEEN 10 AND 20"

3.5.10. Using custom filters

Fast DDS API supports the creation and later registration of user’s custom filters to be used in the creation of a ContentFilteredTopic. Required steps for using a Custom Filter are:

3.5.10.1. Creating the Custom Filter

A custom filter must be implemented by a class which inherits from IContentFilter. Only one function must be implemented, overriding evaluate(). Each time a sample is received by a DataReader, this function is called with next arguments.

  • payload - The serialized payload of the sample which the custom filter has to evaluate.

  • sample_info - The extra information which accompanies the sample.

  • reader_guid - The GUID of the reader for which the filter is being evaluated.

The function returns a boolean where true implies the sample is accepted and false rejects the sample.

Next snippet code shows an example of Custom Filter which deserialize the index field from a serialized sample and rejects samples where index > low_mark_ and index < high_mark_.

class MyCustomFilter : public IContentFilter
{
public:

    MyCustomFilter(
            int low_mark,
            int high_mark)
        : low_mark_(low_mark)
        , high_mark_(high_mark)
    {
    }

    bool evaluate(
            const SerializedPayload& payload,
            const FilterSampleInfo& sample_info,
            const GUID_t& reader_guid) const override
    {
        // Deserialize the `index` field from the serialized sample.
        /* IDL
         *
         * struct HelloWorld
         * {
         *     long index;
         *     string message;
         * }
         */
        eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(payload.data), payload.length);
        eprosima::fastcdr::Cdr deser(fastbuffer);
        // Deserialize encapsulation.
        deser.read_encapsulation();
        int index = 0;

        // Deserialize `index` field.
        try
        {
            deser >> index;
        }
        catch (eprosima::fastcdr::exception::NotEnoughMemoryException& exception)
        {
            return false;
        }

        // Custom filter: reject samples where index > low_mark_ and index < high_mark_.
        if (index > low_mark_ && index < high_mark_)
        {
            return false;
        }

        return true;
    }

private:

    int low_mark_ = 0;
    int high_mark_ = 0;

};
3.5.10.2. Creating the Factory for the Custom Filter

Fast DDS creates filters through a factory. Therefore a factory which provides instantiating of a Custom Filter must be implemented.

A Custom Filter’s factory has to inherit from IContentFilterFactory. This interface requires two functions to be implemented.

Each time a Custom Filter has to be created or updated, create_contentfilteredtopic() calls internally create_content_filter() with these arguments:

  • filter_class_name - Filter class name for which the factory is being called. It allows using the same factory for different filter classes.

  • type_name - Type name of the topic being filtered.

  • data_type - Type support object of the topic being filtered.

  • filter_expression - Custom filter expression.

  • filter_parameters - Values to set for the filter parameters (where custom filter expression has its pattern to substitute them).

  • filter_instance - When a filter is being created, it will be nullptr on input, and will have the pointer to the created filter instance on output. When a filter is being updated, it will have a previously returned pointer on input.

This function should return the result of the operation.

When a Custom Filter should be removed, delete_contentfilteredtopic() calls internally delete_content_filter(). The factory must remove the provided Custom Filter’s instance.

Next snippet code shows an example of Custom Filter’s factory which manages instances of the Custom Filter implemented in the previous section.

class MyCustomFilterFactory : public IContentFilterFactory
{
public:

    ReturnCode_t create_content_filter(
            const char* filter_class_name, // My custom filter class name is 'MY_CUSTOM_FILTER'.
            const char* type_name, // This custom filter only supports one type: 'HelloWorld'.
            const TopicDataType* /*data_type*/, // Not used in this implementation.
            const char* filter_expression, // This Custom Filter doesn't implement a filter expression.
            const ParameterSeq& filter_parameters, // Always need two parameters to be set: low_mark and high_mark.
            IContentFilter*& filter_instance) override
    {
        // Check the ContentFilteredTopic should be created by my factory.
        if (0 != strcmp(filter_class_name, "MY_CUSTOM_FILTER"))
        {
            return RETCODE_BAD_PARAMETER;
        }

        // Check the ContentFilteredTopic is created for the unique type this Custom Filter supports.
        if (0 != strcmp(type_name, "HelloWorld"))
        {
            return RETCODE_BAD_PARAMETER;
        }

        // Check that the two mandatory filter parameters are set.
        if (2 != filter_parameters.length())
        {
            return RETCODE_BAD_PARAMETER;
        }

        // If there is an update, delete previous instance.
        if (nullptr != filter_instance)
        {
            delete(dynamic_cast<MyCustomFilter*>(filter_instance));
        }

        // Instantiation of the Custom Filter.
        filter_instance = new MyCustomFilter(std::stoi(filter_parameters[0]), std::stoi(filter_parameters[1]));

        return RETCODE_OK;
    }

    ReturnCode_t delete_content_filter(
            const char* filter_class_name,
            IContentFilter* filter_instance) override
    {
        // Check the ContentFilteredTopic should be created by my factory.
        if (0 != strcmp(filter_class_name, "MY_CUSTOM_FILTER"))
        {
            return RETCODE_BAD_PARAMETER;
        }

        // Deletion of the Custom Filter.
        delete(dynamic_cast<MyCustomFilter*>(filter_instance));

        return RETCODE_OK;
    }

};
3.5.10.3. Registering the Factory

To be able to use the Custom Filter in an application, the Custom Filter’s factory must be registered in the DomainParticipant. Next snippet code shows how to register a factory through API function register_content_filter_factory().

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create Custom Filter Factory
MyCustomFilterFactory* factory = new MyCustomFilterFactory();


// Registration of the factory
if (RETCODE_OK !=
        participant->register_content_filter_factory("MY_CUSTOM_FILTER", factory))
{
    // Error
    return;
}
3.5.10.4. Creating a ContentFilteredTopic using the Custom Filter

Creating a ContentFilteredTopic explains how to create a ContentFilteredTopic. In the case of using a Custom Filter, create_contentfilteredtopic() has an overload adding an argument to select the Custom Filter.

Next snippet code shows how to create a ContentFilteredTopic using the Custom Filter.

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create the Topic.
Topic* topic =
        participant->create_topic("HelloWorldTopic", "HelloWorld", TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Create a ContentFilteredTopic selecting the Custom Filter and using no expression with two parameters
// Filter expression cannot be an empty one even when it is not used by the custom filter, as that effectively
// disables any filtering
std::string expression = " ";
std::vector<std::string> parameters;
parameters.push_back("10"); // Parameter for low_mark
parameters.push_back("20"); // Parameter for low_mark
ContentFilteredTopic* filter_topic =
        participant->create_contentfilteredtopic("HelloWorldFilteredTopic1", topic, expression, parameters,
                "MY_CUSTOM_FILTER");
if (nullptr == filter_topic)
{
    // Error
    return;
}

// The ContentFilteredTopic instances can then be used to create DataReader objects.
Subscriber* subscriber =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber)
{
    // Error
    return;
}

DataReader* reader_on_filter = subscriber->create_datareader(filter_topic, DATAREADER_QOS_DEFAULT);
if (nullptr == reader_on_filter)
{
    // Error
    return;
}

Important

Even though this specific custom filtering example is not using the filter expression, mind that the expression cannot be an empty string as that disables filtering as explained in Creating a ContentFilteredTopic.

Note

Deleting a ContentFilteredTopic which uses a Custom Filter is done exactly in the same manner explained in Deleting a ContentFilteredTopic.

3.5.11. Where is filtering applied: writer vs reader side

Content filters may be evaluated on either side, as the DataWriter obtains the filter expression from the DataReader during discovery. Filtering on the writer side can save network bandwidth at the cost of increasing CPU usage on the writer.

3.5.11.1. Conditions for writer side filtering

A DataWriter will perform filter evaluation in the DataReader stead whenever all of the following conditions are met; filtering will otherwise be performed by the DataReader.

  • The DataWriter has infinite liveliness. See LivelinessQosPolicy.

  • Communication with the DataReader is neither intra-process nor data-sharing.

  • The DataReader is not using multicast.

  • The DataWriter is filtering for no more DataReaders than the maximum value set on reader_filters_allocation.

    • There is a resource-limit policy on DataWriterQos that controls the allocation behavior of writer-side filtering resources. Setting a maximum value of 0 disables filter evaluation on the writer side. A maximum value of 32 (the default value) means the writer will perform filter evaluation for up to 32 readers.

    • If the DataWriter is evaluating filters for writer_resource_limits.reader_filters_allocation.maximum DataReaders, and a new filtered DataReader is created, then the filter for the newly created DataReader will be evaluated on the reader side.

3.5.11.2. Discovery race condition

On applications where the filter expression and/or the expression parameters are updated, there may be a situation where the DataWriter will apply the old version of the filter until it receives updated information through discovery. This may imply that a publication made a short time after the DataReader updated the filter, but before the updated discovery information is received by the DataWriter, may not be sent to the DataReader, even if the new filter would have told otherwise. Publications made after the updated discovery information is received will use the updated filter.

If some critical application considers this race condition issue unbearable, filtering on the writer side can be disabled by setting the maximum value on reader_filters_allocation to 0.

3.5.12. Fast DDS-Gen for data types source code generation

eProsima Fast DDS comes with a built-in source code generation tool, Fast DDS-Gen, which eases the process of translating an IDL specification of a data type to a functional implementation. Thus, this tool automatically generates the source code of a data type defined using IDL. A basic use of the tool is described below. To learn about all the features that Fast DDS offers, please refer to Fast DDS-Gen section.

3.5.12.1. Basic usage

Fast DDS can be executed by calling fastddsgen on Linux or fastddsgen.bat on Windows. The IDL file containing the data type definition is given with the <IDLfile> argument.

Linux

fastddsgen [<options>] <IDLfile> [<IDLfile> ...]

Windows

fastddsgen.bat [<options>] <IDLfile> [<IDLfile> ...]

Among the available arguments defined in Usage, the main Fast DDS-Gen options for data type source code generation are the following:

  • -replace: It replaces existing files in case the data type files have been previously generated.

  • -help: It lists the currently supported platforms and Visual Studio versions.

  • -no-typeobjectsupport: It disables the automatic generation of the TypeObject representation registration code.

  • -example: It generates a basic example of a DDS application and the files to build it for the given platform. Thus, Fast DDS-Gen tool can generate a sample application using the provided data type, together with a Makefile, to compile it on Linux distributions, and a Visual Studio project for Windows. To see an example of this please refer to tutorial Building a publish/subscribe application.

3.5.12.2. Output files

Fast DDS-Gen outputs several files. Assuming the IDL file had the name “Mytype”, and none of the above options have been defined, these files are:

  • MyType.hpp: Type definition.

  • MyTypePubSubType.cxx/.h: Serialization and deserialization source code for the data type. It also defines the getKey() member function of the MyTypePubSubType class in case the topic implements keys (see Data types with a key).

  • MyTypeCdrAux.hpp/.ipp: Auxiliary methods required by Fast CDR for type encoding and decoding.

  • MyTypeTypeObjectSupport.cxx/.hpp: Auxiliary code required for TypeObject representation generation and registration.

4. RTPS Layer

The lower level RTPS Layer of eprosima Fast DDS serves an implementation of the protocol defined in the RTPS standard. This layer provides more control over the internals of the communication protocol than the DDS Layer, so advanced users have finer control over the library’s functionalities.

4.1. Relation to the DDS Layer

Elements of this layer map one-to-one with elements from the DDS Layer, with a few additions. This correspondence is shown in the following table:

DDS Layer

RTPS Layer

Domain

RTPSDomain

DomainParticipant

RTPSParticipant

DataWriter

RTPSWriter

DataReader

RTPSReader

4.2. How to use the RTPS Layer

We will now go over the use of the RTPS Layer like we did with the DDS Layer one, explaining the new features it presents.

We recommend you to look at the example describing how to use the RTPS layer that come with the distribution while reading this section. It is located in examples/cpp/rtps.

4.2.1. Managing the Participant

Creating a RTPSParticipant is done with RTPSDomain::createParticipant(). RTPSParticipantAttributes structure is used to configure the RTPSParticipant upon creation.

RTPSParticipantAttributes participant_attr;
participant_attr.setName("participant");
RTPSParticipant* participant = RTPSDomain::createParticipant(0, participant_attr);

4.2.2. Managing the Writers and Readers

As the RTPS standard specifies, RTPSWriters and RTPSReaders are always associated with a History element. In the DDS Layer, its creation and management is hidden, but in the RTPS Layer, you have full control over its creation and configuration.

Writers are created with RTPSDomain::createRTPSWriter() and configured with a WriterAttributes structure. They also need a WriterHistory which is configured with a HistoryAttributes structure.

HistoryAttributes history_attr;
WriterHistory* history = new WriterHistory(history_attr);
WriterAttributes writer_attr;
RTPSWriter* writer = RTPSDomain::createRTPSWriter(participant, writer_attr, history);

Similar to the creation of Writers, Readers are created with RTPSDomain::createRTPSReader() and configured with a ReaderAttributes structure. A HistoryAttributes structure is used to configure the required ReaderHistory. Note that in this case, you can provide a specialization of ReaderListener class that implements your callbacks:

class MyReaderListener : public ReaderListener
{
    // Callbacks override
};
MyReaderListener listener;
HistoryAttributes history_attr;
ReaderHistory* history = new ReaderHistory(history_attr);
ReaderAttributes reader_attr;
RTPSReader* reader = RTPSDomain::createRTPSReader(participant, reader_attr, history, &listener);

4.2.3. Using the History to Send and Receive Data

In the RTPS Protocol, Readers and Writers save the data about a topic in their associated Histories. Each piece of data is represented by a Change, which eprosima Fast DDS implements as CacheChange_t. Changes are always managed by the History.

You can add a new CacheChange_t to the History of the Writer to send data. The procedure is as follows:

  1. Request a CacheChange_t from the Writer with RTPSWriter::new_change(). In order to allocate enough memory, you need to provide a callback that returns the maximum number bytes in the payload.

  2. Fill the CacheChange_t with the data.

  3. Add it to the History with WriterHistory::add_change().

The Writer will take care of everything to communicate the data to the Readers.

// Request a change from the history
CacheChange_t* change = history->create_change(255, ALIVE);
// Write serialized data into the change
change->serializedPayload.length = sprintf((char*) change->serializedPayload.data, "My example string %d", 2) + 1;
// Insert change into the history. The Writer takes care of the rest.
history->add_change(change);

If your topic data type has several fields, you will have to provide functions to serialize and deserialize your data in and out of the CacheChange_t. Fast DDS-Gen does this for you.

You can receive data from within the ReaderListener::onNewCacheChangeAdded callback, as we did in the DDS Layer:

  1. The callback receives a CacheChange_t parameter containing the received data.

  2. Process the data within the received CacheChange_t.

  3. Inform the Reader’s History that the change is not needed anymore.

class MyReaderListener : public ReaderListener
{
public:

    MyReaderListener()
    {
    }

    ~MyReaderListener()
    {
    }

    void onNewCacheChangeAdded(
            RTPSReader* reader,
            const CacheChange_t* const change)
    {
        // The incoming message is enclosed within the `change` in the function parameters
        printf("%s\n", change->serializedPayload.data);
        // Once done, remove the change
        reader->get_history()->remove_change((CacheChange_t*)change);
    }

};

4.2.4. Managing the Builtin Transports

DDS uses the Transport Layer to allow communication between DDS entities. eProsima Fast DDS comes with five transports already implemented. However, these transports are not always exclusive between them and in some cases they can be used simultaneously.

You can choose what transports you want to use by disabling the use of builtin transports and manually adding them (see TransportConfigQos) or using the default builtin transports behavior and selecting one of the configuration options listed below. Each option modifies the kind of transports that will be instantiated.

Builtin Transports Options

Description

NONE

No transport will be instantiated. Hence, the user must manually add the desired
transports. Otherwise, the participant creation will fail.

DEFAULT

UDPv4 and SHM transports will be instantiated. SHM transport has priority over the UDPv4
transport. Meaning that SHM will always be used when possible.

DEFAULTv6

UDPv6 and SHM transports will be instantiated. SHM transport has priority over the UDPv4
transport. Meaning that SHM will always be used when possible.

SHM

Only a SHM transport will be instantiated.

UDPv4

Only a UDPv4 transport will be instantiated.

UDPv6

Only a UDPv6 transport will be instantiated.

LARGE_DATA

UDPv4, TCPv4, and SHM transports will be instantiated. However, UDP will only be used
for multicast announcements during the participant discovery phase (see Discovery phases)
while the participant liveliness and the application data delivery occurs over TCP or SHM.
This configuration is useful when working with large data.(See Large Data mode and Fast DDS over TCP).

RTPSParticipantAttributes participant_attr;
participant_attr.setup_transports(eprosima::fastdds::rtps::BuiltinTransports::LARGE_DATA);
RTPSParticipant* participant = RTPSDomain::createParticipant(0, participant_attr);

The same result can also be obtained using the setup_transports() wrapper function of the DomainParticipantQos, XML profiles (see RTPS element type) or the FASTDDS_BUILTIN_TRANSPORTS environment variable (see FASTDDS_BUILTIN_TRANSPORTS).

Note

TCPv4 transport is initialized with the following configuration:

Warning

To obtain a better performance when working with large data messages it is extremely recommended to use the builtin transports configuration options to adjust the transport to the specific needs of the application. Please refer to Large Data with configuration options for more information about how to configure it.

4.3. Configuring Readers and Writers

One of the benefits of using the RTPS Layer is that it provides new configuration possibilities while maintaining the options from the DDS layer. For example, you can set a Writer or a Reader as a Reliable or Best-Effort endpoint as previously:

writer_attr.endpoint.reliabilityKind = BEST_EFFORT;

4.3.1. Setting the data durability kind

The Durability parameter defines the behavior of the Writer regarding samples already sent when a new Reader matches. eProsima Fast DDS offers three Durability options:

  • VOLATILE (default): Messages are discarded as they are sent. If a new Reader matches after message n, it will start received from message n+1.

  • TRANSIENT_LOCAL: The Writer saves a record of the last k messages it has sent. If a new reader matches after message n, it will start receiving from message n-k

  • TRANSIENT: As TRANSIENT_LOCAL, but the record of messages will be saved to persistent storage, so it will be available if the writer is destroyed and recreated, or in case of an application crash.

To choose your preferred option:

writer_attr.endpoint.durabilityKind = TRANSIENT_LOCAL;

Because in the RTPS Layer you have control over the History, in TRANSIENT_LOCAL and TRANSIENT modes the Writer sends all changes you have not explicitly released from the History.

4.4. Configuring the History

The History has its own configuration structure, the HistoryAttributes.

4.4.1. Changing the maximum size of the payload

You can choose the maximum size of the Payload that can go into a CacheChange_t. Be sure to choose a size that allows it to hold the biggest possible piece of data:

history_attr.payloadMaxSize  = 250; // Defaults to 500 bytes

4.4.2. Changing the size of the History

You can specify a maximum amount of changes for the History to hold and an initial amount of allocated changes:

history_attr.initialReservedCaches = 250; // Defaults to 500
history_attr.maximumReservedCaches = 500; // Defaults to 0 = Unlimited Changes

When the initial amount of reserved changes is lower than the maximum, the History will allocate more changes as they are needed until it reaches the maximum size.

4.5. Using a custom Payload Pool

A Payload is defined as the data the user wants to transmit between a Writer and a Reader. RTPS needs to add some metadata to this Payload in order to manage the communication between the endpoints. Therefore, this Payload is encapsulated inside the SerializedPayload_t field of the CacheChange_t, while the rest of the fields of the CacheChange_t provide the required metadata.

WriterHistory and ReaderHistory provide an interface for the user to interact with these changes: Changes to be transmitted by the Writer are added to its WriterHistory, and changes already processed on the Reader can be removed from the ReaderHistory. In this sense, the History acts as a buffer for changes that are not fully processed yet.

During a normal execution, new changes are added to the History and old ones are removed from it. In order to manage the lifecycle of the Payloads contained in these changes, Readers and Writers use a pool object, an implementation of the IPayloadPool interface. Different pool implementations allow for different optimizations. For example, Payloads of different size could be retrieved from different preallocated memory chunks.

Writers and Readers can automatically select a default Payload pool implementation that best suits the configuration given in HistoryAttributes. However, a custom Payload pool can be given to RTPSDomain::createRTPSWriter() and RTPSDomain::createRTPSReader() functions. Writers and Readers will use the provided pool when a new CacheChange_t is requested or released.

4.5.1. IPayloadPool interface

  • IPayloadPool::get_payload overload with size parameter:

    Ties an empty Payload of the requested size to a CacheChange_t instance. The Payload can then be filled with the required data.

  • IPayloadPool::get_payload overload with SerializadPayload parameter:

    Copies the given Payload data to a new Payload from the pool. Each SerializedPayload_t contains a pointer to the pool that allocated its data. This allows certain certain optimizations, like sharing the Payload if the original one comes from this same pool, therefore avoiding the copy operation.

  • IPayloadPool::release_payload:

    Returns the Payload tied to a CacheChange_t to the pool, and breaks the tie.

Important

When implementing a custom Payload pool, make sure that the allocated Payloads fulfill the requirements of standard RTPS serialization. Specifically, the Payloads must be large enough to accommodate the serialized user data plus the 4 octets of the SerializedPayloadHeader as specified in section 10.2 of the RTPS standard.

For example, if we know the upper bound of the serialized user data, we may consider implementing a pool that always allocates Payloads of a fixed size, large enough to hold any of this data. If the serialized user data has at most N octets, then the allocated Payloads must have at least N+4 octets.

Note that the size requested to IPayloadPool::get_payload already considers this 4 octet header.

4.5.2. Default Payload pool implementation

If no custom Payload pool is provided to the Writer or Reader, Fast DDS will automatically use the default implementation that best matches the memoryPolicy configuration of the History.

PREALLOCATED_MEMORY_MODE

All payloads will have a data buffer of fixed size, equal to the value of payloadMaxSize, regardless of the size requested to IPayloadPool::get_payload. Released Payloads can be reused for another CacheChange_t. This reduces memory allocation operations at the cost of higher memory usage.

During the initialization of the History, initialReservedCaches Payloads are preallocated for the initially allocated CacheChange_t.

PREALLOCATED_WITH_REALLOC_MEMORY_MODE

Payloads are guaranteed to have a data buffer at least as large as the maximum between the requested size and payloadMaxSize. Released Payloads can be reused for another CacheChange_t. If there is at least one free Payload with a buffer size equal or larger to the requested one, no memory allocation is done.

During the initialization of the History, initialReservedCaches Payloads are preallocated for the initially allocated CacheChange_t.

DYNAMIC_RESERVE_MEMORY_MODE

Every time a Payload is requested, a new one is allocated in memory with the appropriate size. payloadMaxSize is ignored. The memory of released Payloads is always deallocated, so there are never free Payloads in the pool. This reduces memory usage at the cost of frequent memory allocations.

No preallocation of Payloads is done in the initialization of the History,

DYNAMIC_REUSABLE_MEMORY_MODE

Payloads are guaranteed to have a data buffer at least as large as the requested size. payloadMaxSize is ignored.

Released Payloads can be reused for another CacheChange_t. If there is at least one free Payload with a buffer size equal or larger to the requested one, no memory allocation is done.

4.5.3. Example using a custom Payload pool

// A simple payload pool that reserves and frees memory each time
class CustomPayloadPool : public IPayloadPool
{
    bool get_payload(
            uint32_t size,
            SerializedPayload_t& payload) override
    {
        // Reserve new memory for the payload buffer
        octet* payload_buff = new octet[size];

        // Assign the payload buffer to the CacheChange and update sizes
        payload.data = payload_buff;
        payload.length = size;
        payload.max_size = size;

        // Tell the CacheChange who needs to release its payload
        payload.payload_owner = this;

        return true;
    }

    bool get_payload(
            const SerializedPayload_t& data,
            SerializedPayload_t& payload)
    {
        // Reserve new memory for the payload buffer
        octet* payload_buff = new octet[data.length];

        // Copy the data
        memcpy(payload_buff, data.data, data.length);

        // Tell the CacheChange who needs to release its payload
        payload.payload_owner = this;

        // Assign the payload buffer to the CacheChange and update sizes
        payload.data = payload_buff;
        payload.length = data.length;
        payload.max_size = data.length;

        return true;
    }

    bool release_payload(
            SerializedPayload_t& payload) override
    {
        // Ensure precondition
        if (this != payload.payload_owner)
        {
            std::cerr << "Trying to release a payload buffer allocated by a different PayloadPool." << std::endl;
            return false;
        }

        // Dealloc the buffer of the payload
        delete[] payload.data;

        // Reset sizes and pointers
        payload.data = nullptr;
        payload.length = 0;
        payload.max_size = 0;

        // Reset the owner of the payload
        payload.payload_owner = nullptr;

        return true;
    }

};

std::shared_ptr<CustomPayloadPool> payload_pool = std::make_shared<CustomPayloadPool>();

// A writer using the custom payload pool
HistoryAttributes writer_history_attr;
WriterHistory* writer_history = new WriterHistory(writer_history_attr, payload_pool);
WriterAttributes writer_attr;
RTPSWriter* writer = RTPSDomain::createRTPSWriter(participant, writer_attr, writer_history);

// A reader using the same instance of the custom payload pool
HistoryAttributes reader_history_attr;
ReaderHistory* reader_history = new ReaderHistory(reader_history_attr);
ReaderAttributes reader_attr;
RTPSReader* reader = RTPSDomain::createRTPSReader(participant, reader_attr, payload_pool, reader_history);

// Write and Read operations work as usual, but take the Payloads from the pool.
// Requesting a change to the Writer will provide one with an empty Payload taken from the pool
CacheChange_t* change = writer_history->create_change(255, ALIVE);

// Write serialized data into the change and add it to the history
change->serializedPayload.length = sprintf((char*) change->serializedPayload.data, "My example string %d", 2) + 1;
writer_history->add_change(change);

5. Discovery

Fast DDS, as a Data Distribution Service (DDS) implementation, provides discovery mechanisms that allow for automatically finding and matching DataWriters and DataReaders across DomainParticipants so they can start sharing data. This discovery is performed, for all the mechanisms, in two phases.

5.1. Discovery phases

  1. Participant Discovery Phase (PDP): During this phase the DomainParticipants acknowledge each other’s existence. To do that, each DomainParticipant sends periodic announcement messages, which specify, among other things, unicast addresses (IP and port) where the DomainParticipant is listening for incoming meta and user data traffic. Two given DomainParticipants will match when they exist in the same DDS Domain. By default, the announcement messages are sent using well-known multicast addresses and ports (calculated using the DomainId). Furthermore, it is possible to specify a list of addresses to send announcements using unicast (see in Initial peers). Moreover, it is also possible to configure the periodicity of such announcements (see Discovery Configuration).

  2. Endpoint Discovery Phase (EDP): During this phase, the DataWriters and DataReaders acknowledge each other. To do that, the DomainParticipants share information about their DataWriters and DataReaders with each other, using the communication channels established during the PDP. This information contains, among other things, the Topic and data type (see Topic). For two endpoints to match, their topic and data type must coincide. Once DataWriter and DataReader have matched, they are ready for sending/receiving user data traffic.

Important

It is possible to use the PDP phase to transmit information about the host, user, and process (physical information) in which the DomainParticipant is running. Please refer to Physical Data in Discovery Information for more information about how to configure the transmitted physical data.

5.2. Discovery mechanisms

Fast DDS provides the following discovery mechanisms:

  • Simple Discovery: This is the default mechanism. It upholds the RTPS standard for both PDP and EDP, and therefore provides compatibility with any other DDS and RTPS implementations.

  • Static Discovery: This mechanisms uses the Simple Participant Discovery Protocol (SPDP) for the PDP phase (as specified by the RTPS standard), but allows for skipping the Simple Endpoint Discovery Protocol (SEDP) phase when all the DataWriters’ and DataReaders’ IPs and ports, data types, and Topics are known beforehand.

  • Discovery Server: This discovery mechanism uses a centralized discovery architecture, where a DomainParticipant, referred as Server, acts as a hub for meta traffic discovery.

  • Manual Discovery: This mechanism is only compatible with the RTPS layer. It disables the PDP, letting the user to manually match and unmatch RTPSParticipants, RTPSReaders, and RTPSWriters using whatever external meta-information channel of its choice. Therefore, the user must access the RTPSParticipant implemented by the DomainParticipant and directly match the RTPS Entities.

5.3. Discovery settings

The following sections list and describe the settings available for each of the previously defined discovery mechanisms, as well as how to define the DomainParticipantListener discovery callbacks.

5.3.1. General Discovery Settings

Some discovery settings are shared across the different discovery mechanisms. These settings are defined under the builtin public data member of the WireProtocolConfigQos class. These are:

Name

Description

Type

Default

Discovery Protocol

The discovery protocol to use
(see Discovery mechanisms).

DiscoveryProtocol

SIMPLE

Ignore Participant flags

Filter discovery traffic for
DomainParticipants in the
same process, in different
processes, or in different hosts.

ParticipantFilteringFlags

NO_FILTER

Lease Duration

Indicates for how much time
should a remote DomainParticipant
consider the local DomainParticipant
to be alive.

Duration_t

20 s

Announcement Period

The period for the DomainParticipant
to send PDP announcements.

Duration_t

3 s

5.3.1.1. Discovery Protocol

Specifies the discovery protocol to use (see Discovery mechanisms). The possible values are:

Discovery Mechanism

Possible values

Description

Simple

SIMPLE

Simple discovery protocol as specified in the RTPS standard.

Discovery Server

SERVER

The DomainParticipant acts as a hub for discovery traffic, receiving
and distributing discovery information.

CLIENT

The DomainParticipant acts as a client for discovery traffic.
It sends its discovery information to the server, and it receives
only the information that is relevant to it.

SUPER_CLIENT

The DomainParticipant acts as a client for discovery traffic.
It sends its discovery information to the server, and it receives
all other discovery information from the server.

BACKUP

Creates a SERVER DomainParticipant which has a persistent sqlite
database. A BACKUP server can load the a database on start.
This type of sever makes the Discovery Server architecture
resilient to server destruction.

Manual

NONE

Disables PDP phase, therefore there is no EDP phase.
All matching must be done manually through the
addReaderLocator, addReaderProxy, addWriterProxy
RTPS layer methods.

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        DiscoveryProtocol::SIMPLE;
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="participant_discovery_protocol">
            <rtps>
                <builtin>
                    <discovery_config>
                        <discoveryProtocol>SIMPLE</discoveryProtocol>
                    </discovery_config>
                </builtin>
            </rtps>
        </participant>
    </profiles>
</dds>
5.3.1.2. Ignore Participant flags

Defines a filter to ignore some discovery traffic when received. This is useful to add an extra level of DomainParticipant isolation. The possible values are:

Possible values

Description

NO_FILTER

All Discovery traffic is processed.

FILTER_DIFFERENT_HOST

Discovery traffic from another host is discarded.

FILTER_DIFFERENT_PROCESS

Discovery traffic from another process on the same host is discarded.

FILTER_SAME_PROCESS

Discovery traffic from DomainParticipant’s own process is discarded.

FILTER_DIFFERENT_PROCESS | FILTER_SAME_PROCESS

Discovery traffic from DomainParticipant’s own host is discarded.

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.ignoreParticipantFlags =
        static_cast<eprosima::fastdds::rtps::ParticipantFilteringFlags>(
    ParticipantFilteringFlags::FILTER_DIFFERENT_PROCESS |
    ParticipantFilteringFlags::FILTER_SAME_PROCESS);
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="participant_discovery_ignore_flags">
            <rtps>
                <builtin>
                    <discovery_config>
                        <ignoreParticipantFlags>FILTER_DIFFERENT_PROCESS | FILTER_SAME_PROCESS</ignoreParticipantFlags>
                    </discovery_config>
                </builtin>
            </rtps>
        </participant>
    </profiles>
</dds>

Note

To configure a DomainParticipant to not receive data from its own DataWriters, please refer to Ignore Local Endpoints.

5.3.1.3. Lease Duration

Indicates for how much time should a remote DomainParticipant consider the local DomainParticipant to be alive. If the liveliness of the local DomainParticipant has not being asserted within this time, the remote DomainParticipant considers the local DomainParticipant dead and destroys all the information regarding the local DomainParticipant and all its endpoints.

The local DomainParticipant’s liveliness is asserted on the remote DomainParticipant any time the remote DomainParticipant receives any kind of traffic from the local DomainParticipant.

The lease duration is specified as a time expressed in seconds and nanosecond using a Duration_t.

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.leaseDuration = Duration_t(10, 20);
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="participant_discovery_lease_duration">
            <rtps>
                <builtin>
                    <discovery_config>
                        <leaseDuration>
                            <sec>10</sec>
                            <nanosec>20</nanosec>
                        </leaseDuration>
                    </discovery_config>
                </builtin>
            </rtps>
        </participant>
    </profiles>
</dds>
5.3.1.4. Announcement Period

It specifies the periodicity of the DomainParticipant’s PDP announcements. For liveliness’ sake it is recommend that the announcement period is shorter than the lease duration, so that the DomainParticipant’s liveliness is asserted even when there is no data traffic. It is important to note that there is a trade-off involved in the setting of the announcement period, i.e. too frequent announcements will bloat the network with meta traffic, but too scarce ones will delay the discovery of late joiners.

DomainParticipant’s announcement period is specified as a time expressed in seconds and nanosecond using a Duration_t.

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod = Duration_t(1, 2);
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="participant_discovery_lease_announcement">
            <rtps>
                <builtin>
                    <discovery_config>
                        <leaseAnnouncement>
                            <sec>1</sec>
                            <nanosec>2</nanosec>
                        </leaseAnnouncement>
                    </discovery_config>
                </builtin>
            </rtps>
        </participant>
    </profiles>
</dds>

5.3.2. SIMPLE Discovery Settings

The SIMPLE discovery protocol resolves the establishment of the end-to-end connection between various DDS Entities. eProsima Fast DDS implements the SIMPLE discovery protocol to provide compatibility with the RTPS standard. The specification splits up the SIMPLE discovery protocol into two independent protocols:

  • Simple Participant Discovery Protocol (SPDP): specifies how DomainParticipants discover each other in the network; it announces and detects the presence of DomainParticipants within the same domain.

  • Simple Endpoint Discovery Protocol (SEDP): defines the protocol adopted by the discovered DomainParticipants for the exchange of information in order to discover the DDS Entities contained in each of them, i.e. the DataWriter and DataReader.

Name

Description

Initial Announcements

It defines the behavior of the DomainParticipants initial announcements.

Simple EDP Attributes

It defines the use of the SIMPLE protocol as a discovery protocol.

Initial peers

A list of DomainParticipant’s IP/port pairs to which the SPDP announcements are sent.

5.3.2.1. Initial Announcements

RTPS standard simple discovery mechanism requires the DomainParticipants to send announcements of their presence in the domain. These announcements are not delivered in a reliable fashion, and can be disposed of by the network. In order to avoid the discovery delay induced by message disposal, the initial announcement can be set up to make several shots, in order to increase proper reception chances. See InitialAnnouncementConfig.

Initial announcements only take place upon participant creation. Once this phase is over, the only announcements enforced are the standard ones based on the leaseDuration_announcementperiod period (not the period).

Name

Description

Type

Default

count

It defines the number of announcements to send at start-up.

uint32_t

5

period

It defines the specific period for initial announcements.

Duration_t

100ms

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.initial_announcements.count = 5;
pqos.wire_protocol().builtin.discovery_config.initial_announcements.period = Duration_t(0, 100000000u);
<participant profile_name="participant_profile_simple_discovery">
    <rtps>
        <builtin>
            <discovery_config>
                <initialAnnouncements>
                    <count>5</count>
                    <period>
                        <nanosec>100000000</nanosec>
                    </period>
                </initialAnnouncements>
            </discovery_config>
        </builtin>
    </rtps>
</participant>
5.3.2.2. Simple EDP Attributes

Name

Description

Type

Default

SIMPLE EDP

It defines the use of the SIMPLE protocol as a discovery
protocol for the EDP phase. A DomainParticipant may
create DataWriters, DataReaders, both or neither.

bool

true

Publication writer and
Subscription reader

It is intended for DomainParticipants that implement only
one or more DataWriters, i.e. do not implement DataReaders.
It allows the creation of only DataReader discovery related EDP endpoints.

bool

true

Publication reader and
Subscription writer

It is intended for DomainParticipants that implement only
one or more DataReaders, i.e. do not implement DataWriters.
It allows the creation of only DataWriter discovery related
EDP endpoints.

bool

true

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol = true;
pqos.wire_protocol().builtin.discovery_config.m_simpleEDP.use_PublicationWriterANDSubscriptionReader = true;
pqos.wire_protocol().builtin.discovery_config.m_simpleEDP.use_PublicationReaderANDSubscriptionWriter = false;
<participant profile_name="participant_profile_qos_discovery_edp">
    <rtps>
        <builtin>
            <discovery_config>
                <EDP>SIMPLE</EDP>
                <simpleEDP>
                    <PUBWRITER_SUBREADER>true</PUBWRITER_SUBREADER>
                    <PUBREADER_SUBWRITER>false</PUBREADER_SUBWRITER>
                </simpleEDP>
            </discovery_config>
        </builtin>
    </rtps>
</participant>
5.3.2.3. Initial peers

According to the RTPS standard (Section 9.6.1.1), each RTPSParticipant must listen for incoming Participant Discovery Protocol (PDP) discovery metatraffic in two different ports, one linked to a multicast address and another one linked to a unicast address. Fast DDS allows for the configuration of an initial peers list which contains one or more such IP-port address pairs corresponding to remote DomainParticipants PDP discovery listening resources, so that the local DomainParticipant will only send its PDP traffic to the IP-port address pairs specified in the initial peers list.

A DomainParticipant’s initial peers list contains the list of IP-port address pairs of all other DomainParticipants with which it will communicate. It is a list of addresses that a DomainParticipant will use in the PDP discovery mechanism, and can hold both multicast and unicast addresses. The default multicast address will be used if the list is empty. Therefore, this approach also applies to those scenarios in which multicast functionality is not available.

According to the RTPS standard (Section 9.6.1.1), the RTPSParticipants’ discovery traffic unicast listening ports are calculated using the following equation: 7400 + 250 * domainID + 10 + 2 * participantID. Thus, if for example a RTPSParticipant operates in Domain 0 (default domain) and its ID is 1, its discovery traffic unicast listening port would be: 7400 + 250 * 0 + 10 + 2 * 1 = 7412. By default eProsima Fast DDS uses as initial peers the Metatraffic Multicast Locators.

The following constitutes an example configuring an Initial Peers list with one peer on host 192.168.10.13 with DomainParticipant ID 1 in domain 0.

Note

There is also the possibility of not defining the initial peer port. In this case, the discovery information would be sent to every port ranging from participantID zero to the maxInitialPeersRange value set in the TransportDescriptorInterface. Consequently, setting this value to at least the maximum expected number of DomainParticipants will ensure discovery and communication.

DomainParticipantQos qos;

// configure an initial peer on host 192.168.10.13.
// The port number corresponds to the well-known port for metatraffic unicast
// on participant ID `1` and domain `0`.
Locator_t initial_peer;
IPLocator::setIPv4(initial_peer, "192.168.10.13");
initial_peer.port = 7412;
qos.wire_protocol().builtin.initialPeersList.push_back(initial_peer);
<!--
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
-->
    <participant profile_name="initial_peers_example_profile" is_default_profile="true">
        <rtps>
            <builtin>
                <initialPeersList>
                    <locator>
                        <udpv4>
                            <address>192.168.10.13</address>
                            <port>7412</port>
                        </udpv4>
                    </locator>
                </initialPeersList>
            </builtin>
        </rtps>
    </participant>

5.3.3. STATIC Discovery Settings

Fast DDS allows for the substitution of the SEDP protocol for the EDP phase with a static version that completely eliminates EDP meta traffic. This can become useful when dealing with limited network bandwidth and a well-known schema of DataWriters and DataReaders. If all DataWriters and DataReaders, and their Topics and data types, are known beforehand, the EDP phase can be replaced with a static configuration of peers. It is important to note that by doing this, no EDP discovery meta traffic will be generated, and only those peers defined in the configuration will be able to communicate. The STATIC discovery related settings are:

Name

Description

STATIC EDP

It activates the STATIC discovery protocol.

STATIC EDP XML Configuration Specification

Specifies an XML content with a description of the remote DataWriters and
DataReaders.

Initial Announcements

It defines the behavior of the DomainParticipant initial announcements (PDP phase).

5.3.3.1. STATIC EDP

To activate the STATIC EDP, the SEDP must be disabled on the WireProtocolConfigQos. This can be done either by code or using an XML configuration file:

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol = false;
pqos.wire_protocol().builtin.discovery_config.use_STATIC_EndpointDiscoveryProtocol = true;
<participant profile_name="participant_profile_static_edp">
    <rtps>
        <builtin>
            <discovery_config>
                <EDP>STATIC</EDP>
            </discovery_config>
        </builtin>
    </rtps>
</participant>

Currently two different formats of exchanging information in the Participant Discovery Phase (PDP) are supported: the default one and another that reduces the network bandwidth used. Static Discovery’s Exchange Format explains how to change this.

5.3.3.2. STATIC EDP XML Configuration Specification

Since activating STATIC EDP suppresses all EDP meta traffic, the information about the remote entities (DataWriters and DataReaders) must be statically specified, which is done using dedicated XML files. A DomainParticipant may load several of such configuration files so that the information about different entities can be contained in one file, or split into different files to keep it more organized. Fast DDS provides a Static Discovery example that implements this EDP discovery protocol.

The following table describes all the possible elements of a STATIC EDP XML configuration file. A full example of such file can be found in STATIC EDP XML Example.

Name

Description

Values

Default

<userId>

Mandatory.
Uniquely identifies the DataReader/DataWriter.

uint16_t

0

<entityID>

EntityId of the DataReader/DataWriter.

uint16_t

0

<expects_inline_qos>

It indicates if QOS is expected inline
(DataReader only).

bool

false

<topicName>

Mandatory.
The topic of the remote DataReader/DataWriter.
Should match with one of the topics of the local DataReaders/DataWriters.

string_255

<topicDataType>

Mandatory.
The data type of the topic.

string_255

<topicKind>

The kind of topic.

NO_KEY
WITH_KEY

NO_KEY

<partitionQos>

The name of a partition of the remote peer.
Repeat to configure several partitions.

string

<unicastLocator>

Unicast locator of the DomainParticipant.
See Locators definition.

<multicastLocator>

Multicast locator of the DomainParticipant.
See Locators definition.

<reliabilityQos>

See the ReliabilityQosPolicy section.

BEST_EFFORT_RELIABILITY_QOS
RELIABLE_RELIABILITY_QOS

BEST_EFFORT_RELIABILITY_QOS

<durabilityQos>

See the DurabilityQosPolicy section.

VOLATILE_DURABILITY_QOS
TRANSIENT_LOCAL_DURABILITY_QOS
TRANSIENT_DURABILITY_QOS

VOLATILE_DURABILITY_QOS

<ownershipQos>

See Ownership QoS.

<livelinessQos>

Defines the liveliness of the remote peer.
See Liveliness QoS.

<disablePositiveAcks>

See DisablePositiveACKsQosPolicy.

See DisablePositiveAcks

5.3.3.2.1. Locators definition

Locators for remote peers are configured using <unicastLocator> and <multicastLocator> tags. These take no value, and the locators are defined using tag elements. Locators defined with <unicastLocator> and <multicastLocator> are accumulative, so they can be repeated to assign several remote endpoints locators to the same peer.

  • address: a mandatory string representing the locator address.

  • port: an optional uint16_t representing a port on that address.

5.3.3.2.2. Ownership QoS

The ownership of the topic can be configured using <ownershipQos> tag. It takes no value, and the configuration is done using tag elements:

  • kind: can be one of SHARED_OWNERSHIP_QOS or EXCLUSIVE_OWNERSHIP_QOS. This element is mandatory withing the tag.

  • strength: an optional uint32_t specifying how strongly the remote DomainParticipant owns the Topic. This QoS can be set on DataWriters only. If not specified, default value is zero.

5.3.3.2.3. Liveliness QoS

The LivelinessQosPolicy of the remote peer is configured using <livelinessQos> tag. It takes no value, and the configuration is done using tag elements:

5.3.3.3. Checking STATIC EDP XML Files

Before loading a static EDP XML file, it would be useful to check its validity and make sure the file will be successfully loaded. This verification can be performed on DomainParticipantFactory using DomainParticipantFactory::check_xml_static_discovery(), using either XML files or the configuration directly, as in the examples below.

// The (file://) flag is optional.
std::string file = "file://static_Discovery.xml";
DomainParticipantFactory* factory = DomainParticipantFactory::get_instance();
if (RETCODE_OK != factory->check_xml_static_discovery(file))
{
    std::cout << "Error parsing xml file " << file << std::endl;
}
// The (data://) flag is required to load the configuration directly.
std::string fileData = "data://<?xml version=\"1.0\" encoding=\"utf-8\"?>" \
        "<staticdiscovery>" \
        "<participant>" \
        "<name>HelloWorldPublisher</name>" \
        "<writer>" \
        "<userId>1</userId>" \
        "<entityID>2</entityID>" \
        "<topicName>HelloWorldTopic</topicName>" \
        "<topicDataType>HelloWorld</topicDataType>" \
        "</writer>" \
        "</participant>" \
        "</staticdiscovery>";
if (RETCODE_OK != factory->check_xml_static_discovery(fileData))
{
    std::cout << "Error parsing xml file data:" << std::endl << fileData << std::endl;
}
5.3.3.3.1. STATIC EDP XML Example

The following is a complete example of a configuration XML file for two remote DomainParticipant, a DataWriter and a DataReader. This configuration must agree with the configuration used to create the remote DataReader/DataWriter. Otherwise, communication between DataReaders and DataWriters may be affected. If any non-mandatory element is missing, it will take the default value. As a rule of thumb, all the elements that were specified on the remote DataReader/DataWriter creation should be configured.

XML

<staticdiscovery>
    <participant>
        <name>HelloWorldSubscriber</name>
        <reader>
            <userId>3</userId>
            <entityID>4</entityID>
            <expects_inline_qos>true</expects_inline_qos>
            <topicName>HelloWorldTopic</topicName>
            <topicDataType>HelloWorld</topicDataType>
            <topicKind>WITH_KEY</topicKind>
            <partitionQos>HelloPartition</partitionQos>
            <partitionQos>WorldPartition</partitionQos>
            <unicastLocator address="192.168.0.128" port="5000"/>
            <unicastLocator address="10.47.8.30" port="6000"/>
            <multicastLocator address="239.255.1.1" port="7000"/>
            <reliabilityQos>BEST_EFFORT_RELIABILITY_QOS</reliabilityQos>
            <durabilityQos>VOLATILE_DURABILITY_QOS</durabilityQos>
            <ownershipQos kind="SHARED_OWNERSHIP_QOS"/>
            <livelinessQos kind="AUTOMATIC_LIVELINESS_QOS" leaseDuration_ms="1000"/>
            <disablePositiveAcks>
                <enabled>true</enabled>
            </disablePositiveAcks>
        </reader>
    </participant>
    <participant>
        <name>HelloWorldPublisher</name>
        <writer>
            <unicastLocator address="192.168.0.120" port="9000"/>
            <unicastLocator address="10.47.8.31" port="8000"/>
            <multicastLocator address="239.255.1.1" port="7000"/>
            <userId>5</userId>
            <entityID>6</entityID>
            <topicName>HelloWorldTopic</topicName>
            <topicDataType>HelloWorld</topicDataType>
            <topicKind>WITH_KEY</topicKind>
            <partitionQos>HelloPartition</partitionQos>
            <partitionQos>WorldPartition</partitionQos>
            <reliabilityQos>BEST_EFFORT_RELIABILITY_QOS</reliabilityQos>
            <durabilityQos>VOLATILE_DURABILITY_QOS</durabilityQos>
            <ownershipQos kind="SHARED_OWNERSHIP_QOS" strength="50"/>
            <livelinessQos kind="AUTOMATIC_LIVELINESS_QOS" leaseDuration_ms="1000"/>
            <disablePositiveAcks>
                <enabled>true</enabled>
                <duration>
                    <sec>300</sec>
                </duration>
            </disablePositiveAcks>
        </writer>
    </participant>
</staticdiscovery>
5.3.3.4. Loading STATIC EDP XML Files

Statically discovered remote DataReaders/DataWriters must define a unique userID on their profile, whose value must agree with the one specified in the discovery configuration XML. This is done by setting the user ID on the DataReaderQos/DataWriterQos:

// Configure the DataWriter
DataWriterQos wqos;
wqos.endpoint().user_defined_id = 1;

// Configure the DataReader
DataReaderQos rqos;
rqos.endpoint().user_defined_id = 3;
<data_writer profile_name="writer_xml_conf_static_discovery">
    <userDefinedID>3</userDefinedID>
</data_writer>

<data_reader profile_name="reader_xml_conf_static_discovery">
    <userDefinedID>5</userDefinedID>
</data_reader>

On the local DomainParticipant, you can load STATIC EDP configuration content specifying the file containing it.

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.static_edp_xml_config("file://RemotePublisher.xml");
pqos.wire_protocol().builtin.discovery_config.static_edp_xml_config("file://RemoteSubscriber.xml");
<participant profile_name="participant_profile_static_load_xml">
    <rtps>
        <builtin>
            <discovery_config>
                <static_edp_xml_config>file://RemotePublisher.xml</static_edp_xml_config>
                <static_edp_xml_config>file://RemoteSubscriber.xml</static_edp_xml_config>
            </discovery_config>
        </builtin>
    </rtps>
</participant>

Or you can specify the STATIC EDP configuration content directly.

C++

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.static_edp_xml_config(
    "data://<?xml version=\"1.0\" encoding=\"utf-8\"?>" \
    "<staticdiscovery><participant><name>RTPSParticipant</name></participant></staticdiscovery>");

5.3.4. Discovery Server Settings

This mechanism is based on a client-server discovery paradigm, i.e. the metatraffic (message exchange among DomainParticipants to identify each other) is managed by one or several server DomainParticipants (left figure), as opposed to simple discovery (right figure), where metatraffic is exchanged using a message broadcast mechanism like an IP multicast protocol. A Discovery-Server tool is available to ease Discovery Server setup and testing.

Note

DDS Domain concept does not apply when enabling the default Discovery Server mechanism, but it applies when using ROS2_EASY_MODE.

_images/discovery-server.svg

Comparison of Discovery Server and Simple discovery mechanisms

5.3.4.1. Key concepts

In this architecture there are several key concepts to understand:

  • The Discovery Server mechanism reuses the RTPS discovery messages structure, as well as the standard DDS DataWriters and DataReaders.

  • Discovery Server DomainParticipants may be clients or servers. The only difference between them is how they handle discovery traffic. The user traffic, that is, the traffic among the DataWriters and DataReaders they create, is role-independent.

  • A SERVER is a participant to which the clients (and maybe other servers) send their discovery information.

    • The role of the server is to redistribute its clients discovery information to its known clients and servers.

    • A server also announces the existence of a new server to its known servers, and vice versa. In this way, a new server can connect to every other existing server in the network by just knowing the existence of one of them. In this way, a mesh topology between servers is created with minimal configuration.

    • The discovery information that is redistributed might come from a direct client connected to the SERVER, or from another server that is redirecting the discovery data from its clients.

    • Known servers will receive all the information from the direct clients known by the server and the participant information of other servers (to announce a new server).

    • Known clients will only receive the information they need to establish communication, i.e. the information about the DomainParticipants, DataWriters, and DataReaders to which they match. This means that the server runs a “matching” algorithm to sort out which information is required by which client.

  • A BACKUP server is a server that persists its discovery database into a file.

    • This type of server can load the network graph from a file on start-up without the need of receiving any client’s information.

    • It can be used to persist the server knowledge about the network between runs, thus securing the server’s information in case of unexpected shutdowns.

    • It is important to note that the discovery times will be negatively affected when using this type of server, since periodically writing to a file is an expensive operation.

  • A CLIENT is a participant that connects to one or more servers from which it receives only the discovery information they require to establish communication with matching endpoints.

    • Clients require prior knowledge of the servers to which they want to link. Basically, it consists of a list of locators where the servers are listening, namely, an IP address and a port. These locators also define the transport protocol (UDP or TCP) the client will use to contact the server.

  • A SUPER_CLIENT is a client that receives the discovery information known by the server, in opposition to clients, which only receive the information they need.

    Note

    A SUPER_CLIENT does not behave as a Server as it only receives the discovery information through the Server to which it is connected. It will not connect to other servers, and it will not redistribute the information it receives. Any DomainParticipant discovered by the Server with no endpoints will not be known by the SUPER_CLIENT.

  • Servers do not require any prior knowledge of their clients, but they must listen in the address specified by the locator provided to the clients. Clients send discovery messages to the servers at regular intervals (ping period) until they receive message reception acknowledgement. From then on, the server knows about the client and will inform it of the relevant discovery information. The same principle applies to a server connecting to another server.

5.3.4.2. Choosing between Client and Server

It is set by the Discovery Protocol general setting. A participant can only play one role (despite the fact that a server may connect to other servers). It is mandatory to fill this value because it defaults to SIMPLE. The examples below shows how to set this parameter both programmatically and using XML.

DomainParticipantQos pqos;

pqos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        DiscoveryProtocol::CLIENT;
pqos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        DiscoveryProtocol::SUPER_CLIENT;
pqos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        DiscoveryProtocol::SERVER;
pqos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        DiscoveryProtocol::BACKUP;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_discovery_protocol_alt" >
        <rtps>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>CLIENT</discoveryProtocol>
                    <!-- alternatives
                    <discoveryProtocol>SERVER</discoveryProtocol>
                    <discoveryProtocol>SUPER_CLIENT</discoveryProtocol>
                    <discoveryProtocol>BACKUP</discoveryProtocol>
                    -->
                    </discovery_config>
            </builtin>
        </rtps>
    </participant>
</profiles>
5.3.4.3. The server locator list

Each server must specify valid locators where it can be reached. Any client must be given proper locators to reach each of its servers. Below are two examples of a server and a client side setup.

5.3.4.3.1. Server side setup

The examples below show how to setup the server locator list and XML tag. Each locator must contain:

  • IP address.

  • Port.

  • Transport protocol (UDPv4/6 or TCPv4/6).

Locator_t locator;
// The default locator kind is UDPv4
locator.kind = LOCATOR_KIND_UDPv4;
IPLocator::setIPv4(locator, 192, 168, 1, 133);
locator.port = 64863;

DomainParticipantQos serverQos;
serverQos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_discovery_server_server_metatraffic">
       <rtps>
            <builtin>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                           <!-- placeholder server UDP address -->
                            <address>192.168.1.113</address>
                            <port>64863</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>

Note that a server can connect to other servers, thus, the following section may also apply.

5.3.4.3.2. Client side setup

Each client must keep a list of locators associated to the servers to which it wants to link.

Note that providing an unreachable locator will result in the client sending ping messages to that direction at regular intervals until it is connected to the same amount of servers that has been configured in the locator list.

Locator_t locator;
// The default locator kind is UDPv4
locator.kind = LOCATOR_KIND_UDPv4;
IPLocator::setIPv4(locator, 192, 168, 1, 133);
locator.port = 64863;

DomainParticipantQos clientQos;
clientQos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_discovery_server_client_metatraffic">
       <rtps>
            <builtin>
                <discovery_config>
                    <discoveryServersList>
                        <locator>
                            <udpv4>
                                <!-- placeholder server UDP address -->
                                <address>192.168.1.113</address>
                                <port>64863</port>
                            </udpv4>
                        </locator>
                    </discoveryServersList>
                </discovery_config>
            </builtin>
        </rtps>
    </participant>
</profiles>

Note

Additionally, a logical port can be specified in the locator. If this parameters is left empty, Fast DDS will automatically assign a logical port equal to the physical port whenever it is needed. This behavior is coherent with the logic implemented in the ROS_DISCOVERY_SERVER environment variable and the Fast DDS CLI tool.

5.3.4.4. Fine tuning discovery server handshake

As explained above the clients send discovery messages to the servers at regular intervals (ping period) until they receive as many message reception acknowledgement as remote locators (server addresses) were specified. Mind that this period also applies for those servers which connect to other servers. The default value for this period is 450 ms, but it can be configured to a different value.

DomainParticipantQos participant_qos;
participant_qos.wire_protocol().builtin.discovery_config.discoveryServer_client_syncperiod =
        Duration_t(0, 250000000);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_ping" >
        <rtps>
            <builtin>
                <discovery_config>
                    <clientAnnouncementPeriod>
                        <!-- change default to 250 ms -->
                        <nanosec>250000000</nanosec>
                    </clientAnnouncementPeriod>
                </discovery_config>
            </builtin>
        </rtps>
    </participant>
</profiles>
5.3.4.5. The GuidPrefix as an optional server unique identifier

The GuidPrefix_t attribute belongs to the RTPS specification and univocally identifies each RTPSParticipant. It consists on 12 bytes, and in Fast DDS is a key for the DomainParticipant used in the DDS domain. Fast DDS defines the DomainParticipant GuidPrefix_t as a public data member of the WireProtocolConfigQos class. In the new Discovery Server mechanism, it is a completely optional parameter. However, it might be required in specific scenarios to operate with Discovery Server entities of Fast DDS v2.x or older, where the GuidPrefix_t was mandatory.

5.3.4.5.1. Server side setup

The examples below show how to manage the corresponding enum data member and XML tag.

// Using the ``>>`` operator and the ``std::istringstream`` type.
DomainParticipantQos serverQos;
std::istringstream("44.53.00.5f.45.50.52.4f.53.49.4d.41") >> serverQos.wire_protocol().prefix;
// Manual setting of the ``unsigned char`` in ASCII format.
eprosima::fastdds::rtps::GuidPrefix_t serverGuidPrefix;
serverGuidPrefix.value[0] = eprosima::fastdds::rtps::octet(0x44);
serverGuidPrefix.value[1] = eprosima::fastdds::rtps::octet(0x53);
serverGuidPrefix.value[2] = eprosima::fastdds::rtps::octet(0x00);
serverGuidPrefix.value[3] = eprosima::fastdds::rtps::octet(0x5f);
serverGuidPrefix.value[4] = eprosima::fastdds::rtps::octet(0x45);
serverGuidPrefix.value[5] = eprosima::fastdds::rtps::octet(0x50);
serverGuidPrefix.value[6] = eprosima::fastdds::rtps::octet(0x52);
serverGuidPrefix.value[7] = eprosima::fastdds::rtps::octet(0x4f);
serverGuidPrefix.value[8] = eprosima::fastdds::rtps::octet(0x53);
serverGuidPrefix.value[9] = eprosima::fastdds::rtps::octet(0x49);
serverGuidPrefix.value[10] = eprosima::fastdds::rtps::octet(0x4d);
serverGuidPrefix.value[11] = eprosima::fastdds::rtps::octet(0x41);

DomainParticipantQos serverQos;
serverQos.wire_protocol().prefix = serverGuidPrefix;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_server_guidprefix" >
        <rtps>
            <prefix>44.53.00.5f.45.50.52.4f.53.49.4d.41</prefix>
        </rtps>
    </participant>
</profiles>

Important

When selecting a GUID prefix for the server, it is important to take into account that Fast DDS also uses this parameter to identify participants in the same host or process and translate locators to localhost or enable intra-process communications. It is recommended to let Fast DDS to automatically generate the GUID prefix to guarantee the correct behavior of these features. Setting two DomainParticipant GUID prefixes as intra-process compatible will result in no communication if the DomainParticipants run in separate processes. For more information, please refer to GUID Prefix considerations for intra-process delivery.

Warning

Launching more than one server using the same GUID prefix is undefined behavior.

5.3.4.6. Modifying remote servers list at run time

Once a server or client is running, it is possible to programmatically modify the participant’s list of remote servers to which the running server or client should connect. This is done by calling DomainParticipant::set_qos() with a DomainParticipantQos which has a modified WireProtocolConfigQos (see WireProtocolConfigQos). This feature allows to include a new remote server into the Discovery Server network or modify the remote server locator in case that the remote server is relaunched with a different listening locator.

Important

The updated list of remote servers will modify the ping routine of a client or server, but it will not affect the already established connections. Hence, deleting a locator from the list will not disconnect the server or client from the remote server. However, it will impede reconnection if the connection is lost.

Note

The remote server list can also be modified using the ROS_DISCOVERY_SERVER environment variable. Please refer to FASTDDS_ENVIRONMENT_FILE for more information.

Warning

It is strongly advised to use either the API or the environment file. Using both at the same time may cause undefined behavior.

// Get existing QoS for the server or client
DomainParticipantQos client_or_server_qos;
client_or_server->get_qos(client_or_server_qos);

/* Create a new server entry to which the client or server should connect */
// Set server's listening locator for PDP
Locator_t locator;
IPLocator::setIPv4(locator, 127, 0, 0, 1);
locator.port = 11812;

/* Update list of remote servers for this client or server */
client_or_server_qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(locator);
if (RETCODE_OK != client_or_server->set_qos(client_or_server_qos))
{
    // Error
    return;
}
5.3.4.7. Configure Discovery Server locators using names

All the examples provided in Discovery Server Settings use IPv4 addresses to specify the servers’ listening locators. However, Fast DDS also allows to specify locator addresses using names.

5.3.4.8. Full example

The following constitutes a full example on how to configure server and client both programmatically and using XML. You may also have a look at the eProsima Fast DDS Github repository, which contains an example similar to the one discussed in this section, as well as multiple other examples for different use cases.

5.3.4.8.1. Server side setup
// Get default participant QoS
DomainParticipantQos server_qos = PARTICIPANT_QOS_DEFAULT;

// Set participant as SERVER
server_qos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        DiscoveryProtocol::SERVER;

// Set SERVER's listening locator for PDP
Locator_t locator;
IPLocator::setIPv4(locator, 127, 0, 0, 1);
locator.port = 11811;
server_qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(locator);

/* Add a remote serve to which this server will connect */
// Set remote SERVER's listening locator for PDP
Locator_t remote_locator;
IPLocator::setIPv4(remote_locator, 127, 0, 0, 1);
remote_locator.port = 11812;

// Add remote SERVER to SERVER's list of SERVERs
server_qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(remote_locator);

// Create SERVER
DomainParticipant* server =
        DomainParticipantFactory::get_instance()->create_participant(0, server_qos);
if (nullptr == server)
{
    // Error
    return;
}
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_server_full_example">
        <rtps>
            <builtin>
                <!-- Set participant as SERVER -->
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                    <!--
                        Set a list of remote servers (locators) to which this
                        server connects.
                    -->
                    <discoveryServersList>
                        <!-- Set REMOTE SERVER's listening locator for PDP -->
                        <locator>
                            <udpv4>
                                <address>127.0.0.1</address>
                                <port>11812</port>
                            </udpv4>
                        </locator>
                    </discoveryServersList>
                </discovery_config>
                <!-- Set OWN SERVER's listening locator for PDP -->
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>127.0.0.1</address>
                            <port>11811</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>
5.3.4.8.2. Client side setup
// Get default participant QoS
DomainParticipantQos client_qos = PARTICIPANT_QOS_DEFAULT;

// Set participant as CLIENT
client_qos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        DiscoveryProtocol::CLIENT;

// Set SERVER's listening locator for PDP
Locator_t locator;
IPLocator::setIPv4(locator, 127, 0, 0, 1);
locator.port = 11811;

// Add remote SERVER to CLIENT's list of SERVERs
client_qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(locator);

// Set ping period to 250 ms
client_qos.wire_protocol().builtin.discovery_config.discoveryServer_client_syncperiod =
        Duration_t(0, 250000000);

// Create CLIENT
DomainParticipant* client =
        DomainParticipantFactory::get_instance()->create_participant(0, client_qos);
if (nullptr == client)
{
    // Error
    return;
}
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_client_full_example">
        <rtps>
            <builtin>
                <discovery_config>
                    <!-- Set participant as CLIENT -->
                    <discoveryProtocol>CLIENT</discoveryProtocol>
                    <!--
                        Set a list of remote servers (locators) to which this
                        client connects.
                    -->
                    <discoveryServersList>
                        <!-- Set REMOTE SERVER's listening locator for PDP -->
                        <locator>
                            <udpv4>
                                <address>127.0.0.1</address>
                                <port>11811</port>
                            </udpv4>
                        </locator>
                    </discoveryServersList>
                    <!-- Set ping period to 250 ms -->
                    <clientAnnouncementPeriod>
                        <nanosec>250000000</nanosec>
                    </clientAnnouncementPeriod>
                </discovery_config>
            </builtin>
        </rtps>
    </participant>
</profiles>
5.3.4.9. Security

Configuring Security on servers and clients is done the same way as for any other participant. This section depicts the limitations imposed by the security enforcement on the communication between clients and servers, and which discovery information is propagated by a server depending on the security configuration of the clients and servers to which it is connected.

It is important to note that for enabling a secure discovery when using Discovery Server, Fast DDS must be compiled with security support (see CMake options), and the Domain Governance Document must explicitly encrypt the discovery.

As in SDP, when using this feature, the Domain Governance Document of all clients and servers connecting to a server must match that of the server, which implies that all DomainParticipants belonging to the same Discovery Server network must configure the discovery protection in the same manner.

Although the server mediates the discovery process and creates connections between clients, the clients themselves still go through the PKI (Public Key Infrastructure) exchange in order to have a secure communication between them.

Important

In order to keep the behavior consistent with the QoS Policies, the server does not check the DomainParticipant Permissions Document of the DomainParticipants that it is connecting.

Important

Security support for Discovery Server is only supported from Fast DDS v2.10.0 onward.

5.3.5. DomainParticipantListener Discovery Callbacks

As stated in DomainParticipantListener, the DomainParticipantListener is an abstract class defining the callbacks that will be triggered in response to state changes on the DomainParticipant. Fast DDS defines three callbacks attached to events that may occur during discovery: on_participant_discovery(), on_data_reader_discovery(), on_data_writer_discovery(). Further information about the DomainParticipantListener is provided in the DomainParticipantListener section. The following is an example of the implementation of DomainParticipantListener discovery callbacks.

class DiscoveryDomainParticipantListener : public DomainParticipantListener
{
    /* Custom Callback on_participant_discovery */
    void on_participant_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::ParticipantDiscoveryStatus status,
            const ParticipantBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        static_cast<void>(participant);
        switch (status){
            case eprosima::fastdds::rtps::ParticipantDiscoveryStatus::DISCOVERED_PARTICIPANT:
            {
                /* Process the case when a new DomainParticipant was found in the domain */
                std::cout << "New DomainParticipant '" << info.participant_name <<
                    "' with ID '" << info.guid.entityId << "' and GuidPrefix '" <<
                    info.guid.guidPrefix << "' discovered." << std::endl;
                /* The following line can be substituted to evaluate whether the discovered participant should be ignored */
                bool ignoring_condition = false;
                if (ignoring_condition)
                {
                    should_be_ignored = true;     // Request the ignoring of the discovered participant
                }
            }
            break;
            case eprosima::fastdds::rtps::ParticipantDiscoveryStatus::CHANGED_QOS_PARTICIPANT:
                /* Process the case when a DomainParticipant changed its QOS */
                break;
            case eprosima::fastdds::rtps::ParticipantDiscoveryStatus::REMOVED_PARTICIPANT:
                /* Process the case when a DomainParticipant was removed from the domain */
                std::cout << "DomainParticipant '" << info.participant_name <<
                    "' with ID '" << info.guid.entityId << "' and GuidPrefix '" <<
                    info.guid.guidPrefix << "' left the domain." << std::endl;
                break;
        }
    }

    /* Custom Callback on_data_reader_discovery */
    void on_data_reader_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::ReaderDiscoveryStatus reason,
            const eprosima::fastdds::rtps::SubscriptionBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        static_cast<void>(participant);
        switch (reason){
            case eprosima::fastdds::rtps::ReaderDiscoveryStatus::DISCOVERED_READER:
            {
                /* Process the case when a new datareader was found in the domain */
                std::cout << "New DataReader subscribed to topic '" << info.topic_name <<
                    "' of type '" << info.type_name << "' discovered";
                /* The following line can be substituted to evaluate whether the discovered datareader should be ignored */
                bool ignoring_condition = false;
                if (ignoring_condition)
                {
                    should_be_ignored = true;     // Request the ignoring of the discovered datareader
                }
            }
            break;
            case eprosima::fastdds::rtps::ReaderDiscoveryStatus::CHANGED_QOS_READER:
                /* Process the case when a datareader changed its QOS */
                break;
            case eprosima::fastdds::rtps::ReaderDiscoveryStatus::REMOVED_READER:
                /* Process the case when a datareader was removed from the domain */
                std::cout << "DataReader subscribed to topic '" << info.topic_name <<
                    "' of type '" << info.type_name << "' left the domain.";
                break;
        }
    }

    /* Custom Callback on_data_writer_discovery */
    void on_data_writer_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::WriterDiscoveryStatus reason,
            const eprosima::fastdds::dds::PublicationBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        static_cast<void>(participant);
        switch (reason){
            case eprosima::fastdds::rtps::WriterDiscoveryStatus::DISCOVERED_WRITER:
            {
                /* Process the case when a new datawriter was found in the domain */
                std::cout << "New DataWriter publishing under topic '" << info.topic_name <<
                    "' of type '" << info.type_name << "' discovered";
                /* The following line can be substituted to evaluate whether the discovered datawriter should be ignored */
                bool ignoring_condition = false;
                if (ignoring_condition)
                {
                    should_be_ignored = true;     // Request the ignoring of the discovered datawriter
                }
            }
            break;
            case eprosima::fastdds::rtps::WriterDiscoveryStatus::CHANGED_QOS_WRITER:
                /* Process the case when a datawriter changed its QOS */
                break;
            case eprosima::fastdds::rtps::WriterDiscoveryStatus::REMOVED_WRITER:
                /* Process the case when a datawriter was removed from the domain */
                std::cout << "DataWriter publishing under topic '" << info.topic_name <<
                    "' of type '" << info.type_name << "' left the domain.";
                break;
        }
    }

};

To use the previously implemented discovery callbacks in DiscoveryDomainParticipantListener class, which inherits from the DomainParticipantListener, an object of this class is created and registered as a listener of the DomainParticipant.

// Create the participant QoS and configure values
DomainParticipantQos pqos;

// Create a custom user DomainParticipantListener
DiscoveryDomainParticipantListener* plistener = new DiscoveryDomainParticipantListener();
// Pass the listener on DomainParticipant creation.
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(
    0, pqos, plistener);

Important

Read more about callbacks and its hierarchy here

6. Transport Layer

The transport layer provides communication services between DDS entities, being responsible of actually sending and receiving messages over a physical transport. The DDS layer uses this service for both user data and discovery traffic communication. However, the DDS layer itself is transport independent, it defines a transport API and can run over any transport plugin that implements this API. This way, it is not restricted to a specific transport, and applications can choose the one that best suits their requirements, or create their own.

eProsima Fast DDS comes with five transports already implemented:

  • UDPv4: UDP Datagram communication over IPv4. This transport is created by default on a new DomainParticipant if no specific transport configuration is given (see UDP Transport).

  • UDPv6: UDP Datagram communication over IPv6 (see UDP Transport).

  • TCPv4: TCP communication over IPv4 (see TCP Transport).

  • TCPv6: TCP communication over IPv6 (see TCP Transport).

  • SHM: Shared memory communication among entities running on the same host. This transport is created by default on a new DomainParticipant if no specific transport configuration is given (see Shared Memory Transport).

Although it is not part of the transport module, intraprocess data delivery and data sharing delivery are also available to send messages between entities on some settings. The figure below shows a comparison between the different transports available in Fast DDS.

_images/transport_comparison.svg

6.1. Transport API

The following diagram presents the classes defined on the transport API of eProsima Fast DDS. It shows the abstract API interfaces, and the classes required to implement a transport.

hide empty members
interface TransportDescriptorInterface
{
    +uint32_t maxMessageSize
    +uint32_t maxInitialPeersRange
}
interface TransportInterface
{
    #int32_t transport_kind_
}
class Locator
{
    +int32_t kind
    +uint32_t port
    +octet[16] address
}
TransportDescriptorInterface <|-- CustomTransportDescriptor
TransportInterface <|-- CustomTransport
CustomTransport <--right CustomTransportDescriptor : create
Locator <--right TransportInterface

Transport API diagram

6.1.1. TransportDescriptorInterface

Any class that implements the TransportDescriptorInterface is known as a TransportDescriptor. It acts as a builder for a given transport, meaning that is allows to configure the transport, and then a new Transport can be built according to this configuration using its create_transport factory member function.

6.1.1.1. Data members

The TransportDescriptorInterface defines the following data members:

Member

Data type

Description

maxMessageSize

uint32_t

Maximum size of a single message in the transport.

maxInitialPeersRange

uint32_t

Number of channels opened with each initial remote peer.

Any implementation of TransportDescriptorInterface should add as many data members as required to full configure the transport it describes.

6.1.2. TransportInterface

A Transport is any class that implements the TransportInterface. It is the object that actually performs the message distribution over a physical transport.

Each Transport class defines its own kind, a unique identifier that is used to check the compatibility of a Locator with a Transport, i.e., determine whether a Locator refers to a Transport or not.

Applications do not create the Transport instance themselves. Instead, applications use a TransportDescriptor instance to configure the desired transport, and add this configured instance to the list of user-defined transports of the DomainParticipant. The DomainParticipant will use the factory function on the TransportDescriptor to create the Transport when required.

DomainParticipantQos qos;

// Create a descriptor for the new transport.
auto udp_transport = std::make_shared<UDPv4TransportDescriptor>();
udp_transport->sendBufferSize = 9216;
udp_transport->receiveBufferSize = 9216;
udp_transport->non_blocking_send = true;

// [OPTIONAL] ThreadSettings configuration
udp_transport->default_reception_threads(eprosima::fastdds::rtps::ThreadSettings{2, 2, 2, 2});
udp_transport->set_thread_config_for_port(12345, eprosima::fastdds::rtps::ThreadSettings{3, 3, 3, 3});

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(udp_transport);

// Avoid using the default transport
qos.transport().use_builtin_transports = false;
6.1.2.1. Data members

The TransportInterface defines the following data members:

Member

Data type

Description

transport_kind_

int32_t

Unique identifier of the transport type.

Note

transport_kind_ is a protected data member for internal use. It cannot be accessed nor modified from the public API. However, users that are implementing a custom Transport need to fill it with a unique constant value in the new implementation.

Currently the following identifiers are used in Fast DDS:

Identifier

Value

Transport type

LOCATOR_KIND_RESERVED

0

None. Reserved value for internal use.

LOCATOR_KIND_UDPv4

1

UDP Transport over IPv4.

LOCATOR_KIND_UDPv6

2

UDP Transport over IPv6.

LOCATOR_KIND_TCPv4

4

TCP Transport over IPv4.

LOCATOR_KIND_TCPv6

8

TCP Transport over IPv6.

LOCATOR_KIND_SHM

16

Shared Memory Transport.

6.1.3. Locator

A Locator_t uniquely identifies a communication channel with a remote peer for a particular transport. For example, on UDP transports, the Locator will contain the information of the IP address and port of the remote peer.

The Locator class is not abstract, and no specializations are implemented for each transport type. Instead, transports should map the data members of the Locator class to their own channel identification concepts. For example, on Shared Memory Transport the address contains a unique ID for the local host, and the port represents the shared ring buffer used to communicate buffer descriptors.

Please refer to Listening Locators for more information about how to configure DomainParticipant to listen to incoming traffic.

6.1.3.1. Data members

The Locator defines the following data members:

Member

Data type

Description

kind

int32_t

Unique identifier of the transport type.

port

uint32_t

The channel port.

address

octet[16]

The channel address.

In TCP, the port of the locator is divided into a physical and a logical port.

  • The physical port is the port used by the network device, the real port that the operating system understands. It is stored in the two least significant bytes of the member port.

  • The logical port is the RTPS port. It is used by the RTPS protocol to distinguish different entities. It is stored in the two most significant bytes of the member port.

In TCP, this distinction allows for several DDS applications using different RTPS ports (logical ports) to share the same physical port, thus only requiring for a single port to be opened for all communications. In UDP there is only the physical port, which is also the RTPS port, and is stored in the two least significant bytes of the member port.

The locator address, represented in 16 bytes, is managed differently depending on whether the protocol used is IPv4 or IPv6.

  • The IPv6 address uses the 16 available bytes to represent a unique and global address.

  • The IPv4 address splits those 16 bytes in the following three sections, ordered from least to greatest significance:

    • 4 bytes LAN IP: Local subnet identification (UDP and TCP).

    • 4 bytes WAN IP: Public IP (TCP only).

    • 8 bytes unused.

                        Locator IPv4 address
+--------+-----------------------------+-----------------------------+
| Unused | WAN address (62.128.41.210) | LAN address (192.168.0.113) |
+--------+-----------------------------+-----------------------------+
 8 bytes       (TCP only) 4 bytes                 4 bytes


                        Locator IPv6 address
+--------------------------------------------------------------------+
|          Address (2001:0000:130F:0000:0000:09C0:876A:130B)         |
+--------------------------------------------------------------------+
                              16 bytes

Check how to manipulate the WAN address in the TCP IPv4 transport descriptor api section.

6.1.3.2. Configuring IP locators with IPLocator

IPLocator is an auxiliary static class that offers methods to manipulate IP based locators. It is convenient when setting up a new UDP Transport or TCP Transport, as it simplifies setting IPv4 and IPv6 addresses, or manipulating ports.

For example, normally users configure the physical port and do not need to worry about logical ports. However, IPLocator allows to manage them if needed.

// We will configure a TCP locator with IPLocator
Locator_t locator;

// Get & set the physical port
uint16_t physical_port = IPLocator::getPhysicalPort(locator);
IPLocator::setPhysicalPort(locator, 5555);

// On TCP locators, we can get & set the logical port
uint16_t logical_port = IPLocator::getLogicalPort(locator);
IPLocator::setLogicalPort(locator, 7400);

// Set WAN address
IPLocator::setWan(locator, "80.88.75.55");

Fast DDS also allows to specify locator addresses using names. When an address is specified by a name, Fast DDS will query the known hosts and available DNS servers to try to resolve the IP address. This address will in turn be used to create the listening locator in the case of server, or as the address of the remote server in the case of clients (and servers that connect to other servers).

Locator_t locator;
auto response = eprosima::fastdds::rtps::IPLocator::resolveNameDNS("localhost");
// Get the first returned IPv4
if (response.first.size() > 0)
{
    IPLocator::setIPv4(locator, response.first.begin()->data());
    locator.port = 11811;
}
// Use the locator to create server or client
<locator>
    <udpv4>
        <port>11811</port>
        <address>localhost</address>
    </udpv4>
</locator>

Warning

Currently, XML only supports loading IP addresses by name for UDP transport.

6.1.4. Chaining of transports

There are use cases where the user needs to pre-process out-coming information before being sent to network and also the incoming information after being received. Transport API offers two interfaces for implementing this kind of functionality: ChainingTransportDescriptor and ChainingTransport.

hide empty members
interface TransportDescriptorInterface
{
    +uint32_t maxMessageSize
    +uint32_t maxInitialPeersRange
}
interface TransportInterface
{
    #int32_t transport_kind_
}
interface ChainingTransportDescriptor
{
    +std::shared_ptr<TransportDescriptorInterface> low_level_descriptor
}
interface ChainingTransport
{
    #std::unique_ptr<TransportInterface> low_level_transport_
    {abstract} bool send(...)
    {abstract} void receive(...)
}
TransportDescriptorInterface <|-- ChainingTransportDescriptor
TransportInterface <|-- ChainingTransport
ChainingTransportDescriptor <|-- CustomChainingTransportDescriptor
ChainingTransport <|-- CustomChainingTransport
CustomChainingTransport <-- CustomChainingTransportDescriptor : create
CustomChainingTransportDescriptor "1" *-- "1" TransportDescriptorInterface : contains
CustomChainingTransport "1" *-- "1" TransportInterface : contains
CustomChainingTransportDescriptor --- UDPv4TransportDescriptor : example
CustomChainingTransport ---  UDPv4Transport : example

These extensions allow to implement a new Transport which depends on another one (called here as low_level_transport_). The user can override the send() function, pre-processing the out-coming buffer before calling the associated low_level_transport_. Also, when a incoming buffer arrives to the low_level_transport_, this one calls the overridden receive() function to allow to pre-process the buffer.

6.1.4.1. ChainingTransportDescriptor

Implementing ChainingTransportDescriptor allows to configure the new Transport and set the low_level_transport_ on which it depends. The associated low_level_transport_ can be any transport which inherits from TransportInterface (including another ChainingTransport).

The ChainingTransportDescriptor defines the following data members:

Member

Data type

Description

low_level_descriptor

std::shared_ptr<TransportDescriptorInterface>

Transport descriptor of the low_level_transport_.

User has to specify the low_level_transport_ in the definition of its new custom transport.

DomainParticipantQos qos;

auto udp_transport = std::make_shared<UDPv4TransportDescriptor>();

// Create a descriptor for the new transport.
// The low level transport will be a UDPv4Transport.
auto custom_transport = std::make_shared<CustomChainingTransportDescriptor>(udp_transport);

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(custom_transport);

// Avoid using the default transport
qos.transport().use_builtin_transports = false;
6.1.4.2. ChainingTransport

This interface forces the user to implement send() and receive() functions. The idea is to pre-process the buffer and after, call to the next level.

class CustomChainingTransport : public eprosima::fastdds::rtps::ChainingTransport
{

public:

    CustomChainingTransport(
            const CustomChainingTransportDescriptor& descriptor)
        : ChainingTransport(descriptor)
        , descriptor_(descriptor)
    {
    }

    eprosima::fastdds::rtps::TransportDescriptorInterface* get_configuration()
    {
        return &descriptor_;
    }

    bool send(
            eprosima::fastdds::rtps::SenderResource* low_sender_resource,
            const std::vector<eprosima::fastdds::rtps::NetworkBuffer>& buffers,
            uint32_t total_bytes,
            eprosima::fastdds::rtps::LocatorsIterator* destination_locators_begin,
            eprosima::fastdds::rtps::LocatorsIterator* destination_locators_end,
            const std::chrono::steady_clock::time_point& timeout) override
    {
        //
        // Preprocess outcoming buffer.
        //

        // Call low level transport
        return low_sender_resource->send(buffers, total_bytes, destination_locators_begin,
                       destination_locators_end, timeout);
    }

    void receive(
            eprosima::fastdds::rtps::TransportReceiverInterface* next_receiver,
            const eprosima::fastdds::rtps::octet* receive_buffer,
            uint32_t receive_buffer_size,
            const eprosima::fastdds::rtps::Locator_t& local_locator,
            const eprosima::fastdds::rtps::Locator_t& remote_locator) override
    {
        //
        // Preprocess incoming buffer.
        //

        // Call upper level
        next_receiver->OnDataReceived(receive_buffer, receive_buffer_size, local_locator, remote_locator);
    }

private:

    CustomChainingTransportDescriptor descriptor_;
};

6.2. UDP Transport

UDP is a connectionless transport, where the receiving DomainParticipant must open a UDP port listening for incoming messages, and the sending DomainParticipant sends messages to this port.

Warning

This documentation assumes the reader has basic knowledge of UDP/IP concepts, since terms like Time To Live (TTL), socket buffers, and port numbering are not explained in detail. However, it is possible to configure a basic UDP transport on Fast DDS without this knowledge.

6.2.1. UDPTransportDescriptor

eProsima Fast DDS implements UDP transport for both UDPv4 and UDPv6. Each of these transports is independent from the other, and has its own TransportDescriptorInterface. However, all their TransportDescriptorInterface data members are common.

The following table describes the common data members for both UDPv4 and UDPv6.

Member

Data type

Default

Description

sendBufferSize

uint32_t

0

Size of the sending buffer of the socket (octets).

receiveBufferSize

uint32_t

0

Size of the receiving buffer of the socket (octets).

netmask_filter

NetmaskFilterKind

AUTO

See Netmask filtering.

allowlist

vector<pair<string, NetmaskFilterKind>>

Empty vector

List of allowed interfaces with
netmask filter configuration.
See Allowlist.

blocklist

vector<string>

Empty vector

List of blocked interfaces. See Blocklist.

interfaceWhiteList

vector<string>

Empty vector

List of allowed interfaces. See Interface Whitelist.

TTL

uint8_t

1

Time to live, in number of hops.

m_output_udp_socket

uint16_t

0

Port number for the outgoing messages.

non_blocking_send

bool

false

Do not block on send operations (*).

default_reception_threads

ThreadSettings

Default ThreadSettings for the reception threads.

reception_threads

std::map<uint32_t, ThreadSettings>

ThreadSettings for the reception threads on specific ports.

Note

When non_blocking_send is set to true, send operations will return immediately if the buffer is full, but no error will be returned to the upper layer. This means that the application will behave as if the datagram is sent and lost. This value is specially useful on high-frequency best-effort writers.

When set to false, send operations will block until the network buffer has space for the datagram. This may hinder performance on high-frequency writers.

6.2.1.1. UDPv4TransportDescriptor

UDPv4TransportDescriptor has no additional data members from the common ones described in UDPTransportDescriptor.

Note

The kind value for a UDPv4TransportDescriptor is given by the value LOCATOR_KIND_UDPv4.

6.2.1.2. UDPv6TransportDescriptor

UDPv6TransportDescriptor has no additional data members from the common ones described in UDPTransportDescriptor.

Note

The kind value for a UDPv6TransportDescriptor is given by the value LOCATOR_KIND_UDPv6.

6.2.2. Enabling UDP Transport

Fast DDS enables a UDPv4 transport by default. Nevertheless, the application can enable other UDP transports if needed. To enable a new UDP transport in a DomainParticipant, first create an instance of UDPv4TransportDescriptor (for UDPv4) or UDPv6TransportDescriptor (for UDPv6), and add it to the user transport list of the DomainParticipant.

The examples below show this procedure in both C++ code and XML file.

DomainParticipantQos qos;

// Create a descriptor for the new transport.
auto udp_transport = std::make_shared<UDPv4TransportDescriptor>();
udp_transport->sendBufferSize = 9216;
udp_transport->receiveBufferSize = 9216;
udp_transport->non_blocking_send = true;

// [OPTIONAL] ThreadSettings configuration
udp_transport->default_reception_threads(eprosima::fastdds::rtps::ThreadSettings{2, 2, 2, 2});
udp_transport->set_thread_config_for_port(12345, eprosima::fastdds::rtps::ThreadSettings{3, 3, 3, 3});

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(udp_transport);

// Avoid using the default transport
qos.transport().use_builtin_transports = false;
<?xml version="1.0" encoding="UTF-8" ?>
<dds>
    <profiles xmlns="http://www.eprosima.com">
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>udp_transport</transport_id>
                <type>UDPv4</type>
                <sendBufferSize>9216</sendBufferSize>
                <receiveBufferSize>9216</receiveBufferSize>
                <non_blocking_send>true</non_blocking_send>
                <default_reception_threads>
                    <scheduling_policy>2</scheduling_policy>
                    <priority>2</priority>
                    <affinity>2</affinity>
                    <stack_size>2</stack_size>
                </default_reception_threads>
                <reception_threads>
                    <reception_thread port="12345">
                        <scheduling_policy>3</scheduling_policy>
                        <priority>3</priority>
                        <affinity>3</affinity>
                        <stack_size>3</stack_size>
                    </reception_thread>
                </reception_threads>
            </transport_descriptor>
        </transport_descriptors>

        <participant profile_name="UDPParticipant">
            <rtps>
                <userTransports>
                    <transport_id>udp_transport</transport_id>
                </userTransports>
                <useBuiltinTransports>false</useBuiltinTransports>
            </rtps>
        </participant>
    </profiles>
<dds>

6.3. TCP Transport

TCP is a connection oriented transport, so the DomainParticipant must establish a TCP connection to the remote peer before sending data messages. Therefore, one of the communicating DomainParticipants (the one acting as server) must open a TCP port listening for incoming connections, and the other one (the one acting as client) must connect to this port.

Note

The server and client concepts are independent from the DDS concepts of Publisher, Subscriber, DataWriter, and DataReader. Also, these concepts are independent from the eProsima Discovery Server servers and clients (Discovery Server Settings). Any of them can act as a TCP Server or TCP Client when establishing the connection, and the DDS communication will work over this connection.

Warning

This documentation assumes the reader has basic knowledge of TCP/IP concepts, since terms like Time To Live (TTL), Cyclic Redundancy Check (CRC), Transport Layer Security (TLS), socket buffers, and port numbering are not explained in detail. However, it is possible to configure a basic TCP transport on Fast DDS without this knowledge.

6.3.1. TCPTransportDescriptor

eProsima Fast DDS implements TCP transport for both TCPv4 and TCPv6. Each of these transports is independent from the other, and has its own TransportDescriptorInterface. However, they share many of their features, and most of the TransportDescriptorInterface data members are common.

The following table describes the common data members for both TCPv4 and TCPv6.

Member

Data type

Default

Description

sendBufferSize

uint32_t

0

Size of the sending buffer of the socket (octets).

receiveBufferSize

uint32_t

0

Size of the receiving buffer of the socket (octets).

netmask_filter

NetmaskFilterKind

AUTO

See Netmask filtering.

allowlist

vector<pair<string, NetmaskFilterKind>>

Empty vector

List of allowed interfaces with
netmask filter configuration.
See Allowlist.

blocklist

vector<string>

Empty vector

List of blocked interfaces. See Blocklist.

interfaceWhiteList

vector<string>

Empty vector

List of allowed interfaces See Interface Whitelist.

TTL

uint8_t

1

Time to live, in number of hops.

listening_ports

vector<uint16_t>

Empty vector

List of ports to listen as server. If a port is set to 0, an available port will be automatically assigned.

keep_alive_frequency_ms

uint32_t

5000

Frequency of RTCP keep alive requests (in ms).

keep_alive_timeout_ms

uint32_t

15000

Time since sending the last keep alive request to consider a connection as broken (in ms).

max_logical_port

uint16_t

100

Maximum number of logical ports to try during RTCP negotiation.

logical_port_range

uint16_t

20

Maximum number of logical ports per request to try during RTCP negotiation.

logical_port_increment

uint16_t

2

Increment between logical ports to try during RTCP negotiation.

enable_tcp_nodelay

bool

false

Enables the TCP_NODELAY socket option.

non_blocking_send

bool

false

Do not block on send operations (*).

calculate_crc

bool

true

True to calculate and send CRC on message headers.

check_crc

bool

true

True to check the CRC of incoming message headers.

apply_security

bool

false

True to use TLS. See TLS over TCP.

tls_config

TLSConfig

Configuration for TLS. See TLS over TCP.

default_reception_threads

ThreadSettings

Default ThreadSettings for the reception threads.

reception_threads

std::map<uint32_t, ThreadSettings>

ThreadSettings for the reception threads on specific ports.

keep_alive_thread

ThreadSettings

ThreadSettings for the thread keeping alive TCP connections.

accept_thread

ThreadSettings

ThreadSettings for the threads processing incoming TCP connection requests.

tcp_negotiation_timeout

uint32_t

0

Time to wait for logical port negotiation (in ms). If a logical port is under negotiation, it waits for the negotiation to finish up to this timeout before trying to send a message to that port. Setting this option to non-zero values increases the discovery time. Setting it to zero means no wait but could lead to loss of first messages.

Warning

Although the member listening_ports accepts multiple ports, only the first listening port will be effectively used. The rest of the ports will be ignored.

Note

If listening_ports is left empty, the participant will not be able to receive incoming connections but will be able to connect to other participants that have configured their listening ports.

Note

When non_blocking_send is set to true, send operations will return immediately if the send buffer might get full, but no error will be returned to the upper layer. This means that the application will behave as if the packet is sent and lost.

When set to false, send operations will block until the network buffer has space for the packet.

6.3.1.1. TCPv4TransportDescriptor

The following table describes the data members that are exclusive for TCPv4TransportDescriptor.

Member

Data type

Default

Description

wan_addr

octet[4]

[0, 0, 0, 0]

Configuration for WAN. See WAN or Internet Communication over TCPv4.

Note

The kind value for a TCPv4TransportDescriptor is given by the value LOCATOR_KIND_TCPv4.

6.3.1.2. TCPv6TransportDescriptor

TCPv6TransportDescriptor has no additional data members from the common ones described in TCPTransportDescriptor.

Note

The kind value for a TCPv6TransportDescriptor is given by the value LOCATOR_KIND_TCPv6.

6.3.2. Enabling TCP Transport

There are several ways of enabling TCP transport in eprosima Fast DDS. According to the facet of each scenario, one method might suit better than the others.

6.3.2.1. Configuration of Builtin Transports

The first option is to modify the builtin transports that are responsible of the creation of the DomainParticipant transports. The existing configuration that enables TCP transports is LARGE_DATA. This option instantiates a UDPv4, a TCPv4 and a SHM transport, respectively. UDP protocol will be used for multicast announcements during the participant discovery phase (see Discovery phases) while the participant liveliness and the application data delivery occurs over TCP or SHM. This configuration enables auto discovery and does not require to manually set up each participant IP and listening port. Hence, avoiding the typical Server-Client configuration.

Builtin Transports can be configured using the FASTDDS_BUILTIN_TRANSPORTS environment variable (see FASTDDS_BUILTIN_TRANSPORTS), XML profiles (see RTPS element type) or via code.

export FASTDDS_BUILTIN_TRANSPORTS=LARGE_DATA
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <!--
            UDP transport for PDP and SHM/TCPv4 transport for both EDP and application data
        -->
        <participant profile_name="large_data_builtin_transports" is_default_profile="true">
            <rtps>
                <builtinTransports>LARGE_DATA</builtinTransports>
            </rtps>
        </participant>
    </profiles>
</dds>
eprosima::fastdds::dds::DomainParticipantQos qos;
qos.setup_transports(eprosima::fastdds::rtps::BuiltinTransports::LARGE_DATA);

Note

Note that LARGE_DATA configuration of the builtin transports will also create a SHM transport along the UDP and TCP transports. Shared Memory will be used whenever it is possible. Manual configuration will be required if a TCP communication is required when SHM is feasible. (See Large Data Mode).

6.3.2.2. Server-Client Configuration

To set up a Server-Client configuration you need to create an instance of TCPv4TransportDescriptor (for TCPv4) or TCPv6TransportDescriptor (for TCPv6), and add it to the user transport list of the DomainParticipant.

Depending on the TCP transport descriptor settings and network locators defined, the DomainParticipant can act as a TCP Server or TCP Client.

  • TCP Server: If you provide listening_ports on the descriptor, the DomainParticipant will act as TCP server, listening for incoming remote connections on the given ports. The examples below show this procedure in both C++ code and XML file.

    eprosima::fastdds::dds::DomainParticipantQos qos;
    
    // Create a descriptor for the new transport.
    auto tcp_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
    tcp_transport->add_listener_port(5100);
    
    // [OPTIONAL] ThreadSettings configuration
    tcp_transport->default_reception_threads(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
    tcp_transport->set_thread_config_for_port(12345, eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
    tcp_transport->keep_alive_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};
    tcp_transport->accept_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};
    
    // Link the Transport Layer to the Participant.
    qos.transport().user_transports.push_back(tcp_transport);
    
    // Avoid using the default transport
    qos.transport().use_builtin_transports = false;
    
    // [OPTIONAL] Set unicast locators
    eprosima::fastdds::rtps::Locator_t locator;
    locator.kind = LOCATOR_KIND_TCPv4;
    eprosima::fastdds::rtps::IPLocator::setIPv4(locator, "192.168.1.10");
    eprosima::fastdds::rtps::IPLocator::setPhysicalPort(locator, 5100);
    // [OPTIONAL] Logical port default value is 0, automatically assigned.
    eprosima::fastdds::rtps::IPLocator::setLogicalPort(locator, 5100);
    
    qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(locator);
    qos.wire_protocol().default_unicast_locator_list.push_back(locator);
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <dds>
        <profiles xmlns="http://www.eprosima.com">
            <transport_descriptors>
                <transport_descriptor>
                    <transport_id>tcp_server_transport</transport_id>
                    <type>TCPv4</type>
                    <listening_ports>
                        <port>5100</port>
                    </listening_ports>
                    <!-- Optional thread configuration -->
                    <default_reception_threads>
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </default_reception_threads>
                    <reception_threads>
                        <reception_thread port="12345">
                            <scheduling_policy>-1</scheduling_policy>
                            <priority>0</priority>
                            <affinity>0</affinity>
                            <stack_size>-1</stack_size>
                        </reception_thread>
                    </reception_threads>
                    <keep_alive_thread>
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </keep_alive_thread>
                    <accept_thread>
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </accept_thread>
                </transport_descriptor>
            </transport_descriptors>
    
            <participant profile_name="tcp_server_participant">
                <rtps>
                    <userTransports>
                        <transport_id>tcp_server_transport</transport_id>
                    </userTransports>
                    <useBuiltinTransports>false</useBuiltinTransports>
                    <!-- Optional unicast locator set -->
                    <defaultUnicastLocatorList>
                        <locator>
                            <tcpv4>
                                <address>192.168.1.10</address>
                                <physical_port>5100</physical_port>
                                <!-- Optional logical port set -->
                                <port>5100</port>
                            </tcpv4>
                        </locator>
                    </defaultUnicastLocatorList>
                    <!-- Optional metatraffic unicast locator set -->
                    <builtin>
                        <metatrafficUnicastLocatorList>
                            <locator>
                                <tcpv4>
                                    <address>192.168.1.10</address>
                                    <physical_port>5100</physical_port>
                                    <!-- Optional logical port set -->
                                    <port>5100</port>
                                </tcpv4>
                            </locator>
                        </metatrafficUnicastLocatorList>
                    </builtin>
                </rtps>
            </participant>
        </profiles>
    </dds>
    
  • TCP Client: If you provide initialPeersList to the DomainParticipant, it will act as TCP client, trying to connect to the remote servers at the given addresses and ports. The examples below show this procedure in both C++ code and XML file. See Initial peers for more information about their configuration.

    eprosima::fastdds::dds::DomainParticipantQos qos;
    
    // Disable the built-in Transport Layer.
    qos.transport().use_builtin_transports = false;
    
    // Create a descriptor for the new transport.
    // Do not configure any listener port
    auto tcp_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
    qos.transport().user_transports.push_back(tcp_transport);
    
    // [OPTIONAL] ThreadSettings configuration
    tcp_transport->default_reception_threads(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
    tcp_transport->set_thread_config_for_port(12345, eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
    tcp_transport->keep_alive_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};
    tcp_transport->accept_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};
    
    // Set initial peers.
    eprosima::fastdds::rtps::Locator_t initial_peer_locator;
    initial_peer_locator.kind = LOCATOR_KIND_TCPv4;
    eprosima::fastdds::rtps::IPLocator::setIPv4(initial_peer_locator, "192.168.1.10");
    eprosima::fastdds::rtps::IPLocator::setPhysicalPort(initial_peer_locator, 5100);
    // If the logical port is set in the server side, it must be also set here with the same value.
    // If not set in the server side in a unicast locator, do not set it here.
    eprosima::fastdds::rtps::IPLocator::setLogicalPort(initial_peer_locator, 5100);
    
    qos.wire_protocol().builtin.initialPeersList.push_back(initial_peer_locator);
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <dds>
        <profiles xmlns="http://www.eprosima.com">
            <transport_descriptors>
                <transport_descriptor>
                    <transport_id>tcp_client_transport</transport_id>
                    <type>TCPv4</type>
                    <!-- Optional thread configuration -->
                    <default_reception_threads>
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </default_reception_threads>
                    <reception_threads>
                        <reception_thread port="12345">
                            <scheduling_policy>-1</scheduling_policy>
                            <priority>0</priority>
                            <affinity>0</affinity>
                            <stack_size>-1</stack_size>
                        </reception_thread>
                    </reception_threads>
                    <keep_alive_thread>
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </keep_alive_thread>
                    <accept_thread>
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </accept_thread>
                </transport_descriptor>
            </transport_descriptors>
    
            <participant profile_name="tcp_client_participant">
                <rtps>
                    <userTransports>
                        <transport_id>tcp_client_transport</transport_id>
                    </userTransports>
                    <useBuiltinTransports>false</useBuiltinTransports>
                    <builtin>
                        <initialPeersList>
                            <locator>
                                <tcpv4>
                                    <address>192.168.1.10</address>
                                    <physical_port>5100</physical_port>
                                    <!-- To be set if set in server -->
                                    <port>5100</port>
                                </tcpv4>
                            </locator>
                        </initialPeersList>
                    </builtin>
                </rtps>
            </participant>
        </profiles>
    </dds>
    

Note

Manually setting unicast locators is optional. If not setting them or setting them with a logical port of 0, the client’s initial peer shouldn’t set its logical port (or set it to 0). Otherwise, initial peer’s logical port must match server’s unicast logical port.

Delivery Mechanisms example shows how to use and configure a TCP transport.

6.3.3. WAN or Internet Communication over TCPv4

Fast DDS is able to connect through the Internet or other WAN networks when configured properly. To achieve this kind of scenarios, the involved network devices such as routers and firewalls must add the rules to allow the communication.

For example, imagine we have the scenario represented on the following figure:

_images/TCP_WAN.png
  • A DomainParticipant acts as a TCP server listening on port 5100 and is connected to the WAN through a router with public IP 80.80.99.45.

  • Another DomainParticipant acts as a TCP client and has configured the server’s IP address and port in its Initial peers list.

By using set_WAN_address(wan_ip), the WAN IP address is set on the participant’s locators that are communicated during the discovery phase.

Like in the LAN case, manually setting unicast locators is optional. However, in this case, there are some considerations to take into account when setting its IP addresses:

  • Setting the WAN IP address using the setWAN() method in unicast locators is ineffective because it gets overridden by the set_WAN_address() call.

  • For assigning IP addresses to unicast locators, use only the setIPv4() or setIPv6() methods, which are LAN IP setters. There are some configurations which allow using these setters with a WAN IP address.

Depending on whether the server has manually set its metatraffic unicast locators and default unicast locators, the client needs to adjust its initial peer list accordingly:

  • If the server’s unicast locators are configured with the LAN IP address:

    • The initial peer can be set up with only the server’s WAN IP using the LAN IP setter.

    • Alternatively, it can be configured with both the server’s LAN and WAN IP addresses using the LAN setter for the LAN IP and the WAN setter for the WAN IP.

  • If the server’s unicast locators are configured with the WAN IP address:

    • The initial peer must be set up with only the server’s WAN IP using the LAN setter.

    • Alternatively, it can be configured with the WAN IP address using both the LAN and WAN setters.

  • If the server has not set any unicast locators:

    • The initial peer can be configured with only the server’s WAN IP using the LAN setter.

    • Alternatively, it can be configured with both the server’s LAN and WAN IP addresses using the LAN setter for the LAN IP and the WAN setter for the WAN IP.

Note

Manually setting unicast locators is optional. If not setting them or setting them with a logical port of 0, the client’s initial peer shouldn’t set its logical port (or set it to 0). Otherwise, initial peer’s logical port must match server’s unicast logical port.

On the server side, the router must be configured to forward to the TCP server all traffic incoming to port 5100. Typically, a NAT routing of port 5100 to our machine is enough. Any existing firewall should be configured as well.

In addition, to allow incoming connections through a WAN, the TCPv4TransportDescriptor must indicate its public IP address in the wan_addr data member. The following examples show how to configure the DomainParticipant both in C++ and XML.

eprosima::fastdds::dds::DomainParticipantQos qos;

// Create a descriptor for the new transport.
auto tcp_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
tcp_transport->add_listener_port(5100);
tcp_transport->set_WAN_address("80.80.99.45");

// [OPTIONAL] ThreadSettings configuration
tcp_transport->default_reception_threads(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
tcp_transport->set_thread_config_for_port(12345, eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
tcp_transport->keep_alive_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};
tcp_transport->accept_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(tcp_transport);

// Avoid using the default transport
qos.transport().use_builtin_transports = false;

// [OPTIONAL] Set unicast locators (do not use setWAN(), set_WAN_address() overwrites it)
eprosima::fastdds::rtps::Locator_t locator;
locator.kind = LOCATOR_KIND_TCPv4;
// [RECOMMENDED] Use the LAN address of the server
eprosima::fastdds::rtps::IPLocator::setIPv4(locator, "192.168.1.10");
// [ALTERNATIVE] Use server's WAN address. In that case, initial peers must be configured
// only with server's WAN address.
// eprosima::fastdds::rtps::IPLocator::setIPv4(locator, "80.80.99.45");
eprosima::fastdds::rtps::IPLocator::setPhysicalPort(locator, 5100);
// [OPTIONAL] Logical port default value is 0, automatically assigned.
eprosima::fastdds::rtps::IPLocator::setLogicalPort(locator, 5100);

qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(locator);
qos.wire_protocol().default_unicast_locator_list.push_back(locator);
<?xml version="1.0" encoding="UTF-8" ?>
<dds>
    <profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>tcp_server_wan_transport</transport_id>
                <type>TCPv4</type>
                <listening_ports>
                    <port>5100</port>
                </listening_ports>
                <wan_addr>80.80.99.45</wan_addr>
                <!-- Optional thread configuration -->
                <default_reception_threads>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </default_reception_threads>
                <reception_threads>
                    <reception_thread port="12345">
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </reception_thread>
                </reception_threads>
                <keep_alive_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </keep_alive_thread>
                <accept_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </accept_thread>
            </transport_descriptor>
        </transport_descriptors>

        <participant profile_name="tcp_server_wan_participant">
            <rtps>
                <userTransports>
                    <transport_id>tcp_server_wan_transport</transport_id>
                </userTransports>
                <useBuiltinTransports>false</useBuiltinTransports>
                <!-- Optional unicast locator set -->
                <defaultUnicastLocatorList>
                    <locator>
                        <tcpv4>
                            <address>192.168.1.10</address>
                            <!-- Alternatively use WAN address -->
                            <!-- <address>80.80.99.45</address> -->
                            <physical_port>5100</physical_port>
                            <!-- Optional logical port set -->
                            <port>5100</port>
                        </tcpv4>
                    </locator>
                </defaultUnicastLocatorList>
                <!-- Optional metatraffic unicast locator set -->
                <builtin>
                    <metatrafficUnicastLocatorList>
                        <locator>
                            <tcpv4>
                                <address>192.168.1.10</address>
                                <!-- Alternatively use WAN address -->
                                <!-- <address>80.80.99.45</address> -->
                                <physical_port>5100</physical_port>
                                <!-- Optional logical port set -->
                                <port>5100</port>
                            </tcpv4>
                        </locator>
                    </metatrafficUnicastLocatorList>
                </builtin>
            </rtps>
        </participant>
    </profiles>
</dds>

On the client side, the DomainParticipant must be configured with the public IP address and listening_ports of the TCP server as Initial peers.

eprosima::fastdds::dds::DomainParticipantQos qos;

// Disable the built-in Transport Layer.
qos.transport().use_builtin_transports = false;

// Create a descriptor for the new transport.
// Do not configure any listener port
auto tcp_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
// [RECOMMENDED] Use client's WAN address if there are more clients in other local networks.
tcp_transport->set_WAN_address("80.80.99.47");
qos.transport().user_transports.push_back(tcp_transport);

// [OPTIONAL] ThreadSettings configuration
tcp_transport->default_reception_threads(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
tcp_transport->set_thread_config_for_port(12345, eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
tcp_transport->keep_alive_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};
tcp_transport->accept_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};

// Set initial peers.
eprosima::fastdds::rtps::Locator_t initial_peer_locator;
initial_peer_locator.kind = LOCATOR_KIND_TCPv4;
// [RECOMMENDED] Use both WAN and LAN server addresses
eprosima::fastdds::rtps::IPLocator::setIPv4(initial_peer_locator, "192.168.1.10");
eprosima::fastdds::rtps::IPLocator::setWan(initial_peer_locator, "80.80.99.45");
// [ALTERNATIVE] Use server's WAN address only. Valid if server specified its unicast locators
// with its LAN or WAN address.
// eprosima::fastdds::rtps::IPLocator::setIPv4(initial_peer_locator, "80.80.99.45");
eprosima::fastdds::rtps::IPLocator::setPhysicalPort(initial_peer_locator, 5100);
// If the logical port is set in the server side, it must be also set here with the same value.
// If not set in the server side in a unicast locator, do not set it here.
eprosima::fastdds::rtps::IPLocator::setLogicalPort(initial_peer_locator, 5100);

qos.wire_protocol().builtin.initialPeersList.push_back(initial_peer_locator);
<?xml version="1.0" encoding="UTF-8" ?>
<dds>
    <profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>tcp_client_wan_transport</transport_id>
                <type>TCPv4</type>
                <!-- Recommended client's WAN set -->
                <wan_addr>80.80.99.47</wan_addr>
                <!-- Optional thread configuration -->
                <default_reception_threads>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </default_reception_threads>
                <reception_threads>
                    <reception_thread port="12345">
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </reception_thread>
                </reception_threads>
                <keep_alive_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </keep_alive_thread>
                <accept_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </accept_thread>
            </transport_descriptor>
        </transport_descriptors>

        <participant profile_name="tcp_client_wan_participant">
            <rtps>
                <userTransports>
                    <transport_id>tcp_client_wan_transport</transport_id>
                </userTransports>
                <useBuiltinTransports>false</useBuiltinTransports>
                <builtin>
                    <initialPeersList>
                        <locator>
                            <tcpv4>
                                <!-- Recommended use of both WAN and LAN server addresses -->
                                <wan_address>80.80.99.45</wan_address>
                                <address>192.168.1.10</address>
                                <!-- Alternatively use server's WAN addresses only -->
                                <!-- <address>80.80.99.45</address> -->
                                <physical_port>5100</physical_port>
                                <!-- To be set if set in server -->
                                <port>5100</port>
                            </tcpv4>
                        </locator>
                    </initialPeersList>
                </builtin>
            </rtps>
        </participant>
    </profiles>
</dds>

6.3.4. Delivery Mechanisms example

A hello world example suitable for supported delivery mechanisms can be found in the delivery_mechanisms folder. It shows a publisher and a subscriber that communicate through the desired delivery mechanism (which can be set to TCP only).

6.4. Shared Memory Transport

The shared memory (SHM) transport enables fast communications between entities running in the same processing unit/machine, relying on the shared memory mechanisms provided by the host operating system.

Note

Fast DDS utilizes the DomainParticipant’s GuidPrefix_t to identify peers running in the same host. Two participants with identical 4 first bytes on the GuidPrefix_t are considered to be running in the same host. is_on_same_host_as() API is provided to check this condition. Please, take also into account the caveats included in GUID Prefix considerations for intra-process delivery.

SHM transport provides better performance than other network transports like UDP / TCP, even when these transports use loopback interface. This is mainly due to the following reasons:

  • Large message support: Network protocols need to fragment data in order to comply with the specific protocol and network stacks requirements, increasing communication overhead. SHM transport allows the copy of full messages where the only size limit is the machine’s memory capacity.

  • Reduce the number of memory copies: When sending the same message to different endpoints, SHM transport can directly share the same memory buffer with all the destination endpoints. Other protocols require to perform one copy of the message per endpoint.

  • Less operating system overhead: Once initial setup is completed, shared memory transfers require much less system calls than the other protocols. Therefore, there is a performance/time consume gain by using SHM.

6.4.1. Definition of Concepts

This section describes basic concepts to help explain how the Shared Memory Transport works in order to deliver the data messages to the appropriate DomainParticipant. The purpose is not to be an exhaustive reference of the implementation, but to be a comprehensive explanation of each concept, so that users can configure the transport to their needs.

Many of the descriptions in this section will be made following the example use case depicted in the following figure, where Participant 1 sends a data message to Participant 2. Please, refer to the figure when following the definitions.

_images/shm_comm_sequence_diagram.svg

Sequence diagram for Shared Memory Transport

6.4.1.1. Segment

A Segment is a block of shared memory that can be accessed from different processes. Every DomainParticipant that has been configured with Shared Memory Transport creates a segment of shared memory. The DomainParticipant writes to this segment any data it needs to deliver to other DomainParticipants, and the remote DomainParticipants are able to read it directly using the shared memory mechanisms.

Note

Launching any of the processes with a higher privileged user (for instance, root) can lead to communication problems, as processes run by non-privileged users may not be able to write into the memory segment.

Every segment has a segmentId, a 16-character UUID that uniquely identifies each shared memory segment. These segmentIds are used to identify and access the segment of each DomainParticipant.

6.4.1.2. Segment Buffer

A buffer allocated in the shared memory Segment. It works as a container for a DDS message that is placed in the Segment. In other words, each message that the DomainParticipant writes on the Segment will be placed in a different buffer.

6.4.1.3. Buffer Descriptor

It acts as a pointer to a specific Segment Buffer in a specific Segment. It contains the segmentId and the offset of the Segment Buffer from the base of the Segment. When communicating a message to other DomainParticipants, Shared Memory Transport only distributes the Buffer Descriptor, avoiding the copy of the message from a DomainParticipant to another. With this descriptor, the receiving DomainParticipant can access the message written in the buffer, as is uniquely identifies the Segment (through the segmentId) and the Segment Buffer (through its offset).

6.4.1.4. Port

Represents a channel to communicate Buffer Descriptors. It is implemented as a ring-buffer in shared memory, so that any DomainParticipant can potentially read or write information on it. Each port has a unique identifier, a 32 bit number that can be used to refer to the port. Every DomainParticipant that has been configured with Shared Memory Transport creates a port to receive Buffer Descriptors. The identifier of this port is shared during the Discovery, so that remote peers know which port to use when they want to communicate with each DomainParticipant.

DomainParticipants create a listener to their receiving port, so that they can be notified when a new Buffer Descriptor is pushed to the port.

6.4.1.5. Port Health Check

Every time a DomainParticipant opens a Port (for reading or writing), a health check is performed to assess its correctness. The reason is that if one of the processes involved crashes while using a Port, that port can be left inoperative. If the attached listeners do not respond in a given timeout, the Port is considered damaged, and it is destroyed and created again.

6.4.2. SharedMemTransportDescriptor

In addition to the data members defined in the TransportDescriptorInterface, the TransportDescriptor for Shared Memory defines the following ones:

Member

Data type

Default

Accessor / Mutator

Description

segment_size_

uint32_t

512*1024

segment_size()

Size of the shared memory segment
(in octets).

port_queue_capacity_

uint32_t

512

port_queue_capacity()

The size of the listening port
(in messages).

healthy_check_timeout_ms_

uint32_t

1000

healthy_check_timeout_ms()

Timeout for the health check of ports
(in milliseconds).

rtps_dump_file_

string

""

rtps_dump_file()

Full path of the protocol dump file.

default_reception_threads

ThreadSettings

default_reception_threads

Default ThreadSettings for the reception threads.

reception_threads

std::map<uint32_t, ThreadSettings>

reception_threads

ThreadSettings for the reception threads on specific ports.

dump_thread()

ThreadSettings

dump_thread()

ThreadSettings for the SHM dump thread.

If rtps_dump_file_ is not empty, all the shared memory traffic on the DomainParticipant (sent and received) is traced to a file. The output file format is tcpdump hexadecimal text, and can be processed with protocol analyzer applications such as Wireshark. Specifically, to open the file using Wireshark, use the “Import from Hex Dump” option using the “Raw IPv4” encapsulation type.

Note

The kind value for a SharedMemTransportDescriptor is given by the value LOCATOR_KIND_SHM.

Warning

Setting a segment_size() close to or smaller than the data size poses a high risk of data loss, since the write operation will overwrite the buffer during a single send operation.

6.4.3. Enabling Shared Memory Transport

Fast DDS enables a SHM transport by default. Nevertheless, the application can enable other SHM transports if needed. To enable a new SHM transport in a DomainParticipant, first create an instance of SharedMemTransportDescriptor, and add it to the user transport list of the DomainParticipant.

The examples below show this procedure in both C++ code and XML file.

DomainParticipantQos qos;

// Create a descriptor for the new transport.
std::shared_ptr<SharedMemTransportDescriptor> shm_transport =
        std::make_shared<SharedMemTransportDescriptor>();

// [OPTIONAL] ThreadSettings configuration
shm_transport->default_reception_threads(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
shm_transport->set_thread_config_for_port(12345, eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});
shm_transport->dump_thread(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(shm_transport);
<?xml version="1.0" encoding="UTF-8" ?>
<dds>
    <profiles xmlns="http://www.eprosima.com">
        <transport_descriptors>
            <!-- Create a descriptor for the new transport -->
            <transport_descriptor>
                <transport_id>shm_transport</transport_id>
                <type>SHM</type>
                <default_reception_threads> <!-- OPTIONAL -->
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </default_reception_threads>
                <reception_threads> <!-- OPTIONAL -->
                    <reception_thread port="12345">
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </reception_thread>
                </reception_threads>
                <dump_thread> <!-- OPTIONAL -->
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </dump_thread>
            </transport_descriptor>
        </transport_descriptors>

        <participant profile_name="SHMParticipant">
            <rtps>
                <!-- Link the Transport Layer to the Participant -->
                <userTransports>
                    <transport_id>shm_transport</transport_id>
                </userTransports>
            </rtps>
        </participant>
    </profiles>
</dds>

Note

In case that several transports are enabled, the discovery traffic is always performed using the UDP/TCP transport, even if the SHM transport is enabled in both participants running in the same machine. This may cause discovery issues if one or several of the participants only has SHM enabled and other participants use some other transport at the same time. Also, when two participants on the same machine have SHM transport enabled, the user data communication between them is automatically performed by SHM transport only. The rest of the enabled transports are not used between those two participants.

Hint

To configure discovery traffic through Shared Memory, the default builtin transports must be disabled. In that way, communication is performed completely using Shared Memory. The snippet examples below show this procedure in both C++ code and XML file. See Delivery Mechanisms example for a complete example.

DomainParticipantQos qos;

// Create a descriptor for the new transport.
std::shared_ptr<SharedMemTransportDescriptor> shm_transport =
        std::make_shared<SharedMemTransportDescriptor>();

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(shm_transport);

// Explicit configuration of SharedMem transport
qos.transport().use_builtin_transports = false;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <transport_descriptors>
        <!-- Create a descriptor for the new transport -->
        <transport_descriptor>
            <transport_id>shm_transport_only</transport_id>
            <type>SHM</type>
        </transport_descriptor>
    </transport_descriptors>

    <participant profile_name="DisableBuiltinTransportsParticipant">
        <rtps>
            <!-- Link the Transport Layer to the Participant -->
            <userTransports>
                <transport_id>shm_transport_only</transport_id>
            </userTransports>
            <useBuiltinTransports>false</useBuiltinTransports>
        </rtps>
    </participant>
</profiles>

6.4.4. Delivery Mechanisms example

A hello world example suitable for supported delivery mechanisms can be found in the delivery_mechanisms folder. It shows a publisher and a subscriber that communicate through the desired delivery mechanism (which can be set to shared memory only).

6.5. Data-sharing delivery

Fast DDS allows to speed up communications between entities within the same machine by sharing the history of the DataWriter with the DataReader through shared memory. This prevents any of the overhead involved in the transport layer, effectively avoiding any data copy between DataWriter and DataReader.

Note

Fast DDS utilizes the DomainParticipant’s GuidPrefix_t to identify peers running in the same host. Two participants with identical 4 first bytes on the GuidPrefix_t are considered to be running in the same host. is_on_same_host_as() API is provided to check this condition. Please, take also into account the caveats included in GUID Prefix considerations for intra-process delivery.

Use of Data-sharing delivery does not prevent data copies between the application and the DataReader and DataWriter. These can be avoided in some cases using Zero-Copy communication.

Note

Although Data-sharing delivery uses shared memory, it differs from Shared Memory Transport in that Shared Memory is a full-compliant transport. That means that with Shared Memory Transport the data being transmitted must be copied from the DataWriter history to the transport and from the transport to the DataReader. With Data-sharing these copies can be avoided.

6.5.1. Overview

When the DataWriter is created, Fast DDS will pre-allocate a pool of max_samples + extra_samples samples that reside in a shared memory mapped file. When publishing new data, the DataWriter will take a sample from this pool and add it to its history, and notify the DataReader which sample from the pool has the new data.

The DataReader will have access to the same shared memory mapped file, and will be able to access the data published by the DataWriter.

6.5.2. Constraints

This feature is available only if the following requirements are met:

There is also a limitation with the DataReader’s HistoryQos. Using Data-sharing mechanism, the DataWriter’s history is shared with the DataReaders. This means that the effective HistoryQos depth on the DataReader is, at most, the Datawriter’s HistoryQos depth. To avoid confusions, set the DataReaders’ history depth to a value equal or less than the DataWriter’s.

6.5.3. Data-sharing delivery configuration

Data-sharing delivery can be configured in the DataWriter and the DataReader using DataSharingQosPolicy. Four attributes can be configured:

  • The data-sharing delivery kind

  • The shared memory directory

  • The data-sharing domain identifiers.

  • The maximum number of data-sharing domain identifiers.

6.5.3.1. Data-Sharing delivery kind

Can be set to one of three modes:

  • AUTO: If both a DataWriter and DataReader meet the requirements, data-sharing delivery will be used between them. This is the default value.

  • ON: Like AUTO, but the creation of the entity will fail if the requirements are not met.

  • OFF: No data-sharing delivery will be used on this entity.

The following matrix shows when two entities are data-sharing compatible according to their configuration (given that the entity creation does not fail and that both entities have access to a shared memory):

Reader

ON

OFF

AUTO

Writer

ON

Only if they have common domain IDs

No

Only if they have common domain IDs

OFF

No

No

No

AUTO

Only if they have common domain IDs

No

Only if the TopicDataType is bounded
and they have common domain IDs

6.5.3.2. Data-sharing domain identifiers

Each entity defines a set of identifiers that represent a domain to which the entity belongs. Two entities will be able to use data-sharing delivery between them only if both have at least a common domain.

Users can define the domains of a DataWriter or DataReader with the DataSharingQosPolicy. If no domain identifier is provided by the user, the system will create one automatically. This automatic data-sharing domain will be unique for the machine where the entity is running. That is, all entities running on the same machine, and for which the user has configured no user-specific domains, will be able to use data-sharing delivery (given that the rest of requirements are met).

During the discovery phase, entities will exchange their domain identifiers and check if they can use Data-sharing to communicate.

Note

Even though a data-sharing domain identifier is a 64 bit integer, user-defined identifiers are restricted to 16 bit integers.

6.5.3.3. Maximum number of Data-sharing domain identifiers

The maximum number of domain identifiers that are expected to be received from a remote entity during discovery. If the remote entity defines (and sends) more than this number of domain identifiers, the discovery will fail.

By default there is no limit to the number of identifiers. The default value can be changed with the max_domains() function. Defining a finite number allows to preallocate the required memory to receive the list of identifiers during the entity creation, avoiding dynamic memory allocations afterwards. Note that a value of 0 means no limit.

6.5.3.4. Shared memory directory

If a user-defined directory is given for the shared memory files, this directory will be used for the memory-mapped files used for data-sharing delivery. If none is given, the default directory configured for the current system is used.

Configuring a user-defined directory may be useful in some scenarios:

  • To select a file system with Huge TLB enabled for the memory-mapped files.

  • To allow data-sharing delivery between containers that mount the same container.

6.5.4. DataReader and DataWriter history coupling

With traditional Transport Layer delivery, the DataReader and DataWriter keep separate and independent histories, each one with their own copy of the sample. Once the sample is sent through the transport and received by the DataReader, the DataWriter is free to remove the sample from its history without affecting the DataReader.

With data-sharing delivery, the DataReader directly accesses the data instance created by the DataWriter. This means that the samples in both the history of the DataReader and the DataWriter refer to the same object in the shared memory. Therefore, there is a strong coupling in the behavior of the DataReader and DataWriter histories.

Important

If the DataWriter reuses the same sample to publish new data, the DataReader loses access to the old data sample.

Note

The DataWriter can remove the sample from its history, and it will still be available on the DataReader, unless the same sample from the pool is reused to publish a new one.

6.5.4.1. Data acknowledgement

With data-sharing delivery, sample acknowledgment from the DataReader occurs the first time a sample is retrieved by the application (using DataReader::read_next_sample(), DataReader::take_next_sample(), or any of their variations). Once the data has been accessed by the application, the DataWriter is free to reuse that sample to publish new data. The DataReader detects when a sample has been reused and automatically removes it from its history.

This means that subsequent attempts to access the same sample from the DataReader may return no sample at all.

6.5.4.2. Blocking reuse of samples until acknowledged

With KEEP_LAST_HISTORY_QOS or BEST_EFFORT_RELIABILITY_QOS configurations, the DataWriter can remove samples from its history to add new ones, even if they were not acknowledged by the DataReader. In situations where the publishing rate is consistently faster than the rate at which the DataReader can process the samples, this can lead to every sample being reused before the application has a chance to process it, thus blocking the communication at application level.

In order to avoid this situation, the samples in the preallocated pool are never reused unless they have been acknowledged, i.e., they have been processed by the application at least once. If there is no reusable sample in the pool, the writing operation in the DataWriter will be blocked until one is available or until max_blocking_time is reached.

Note that the DataWriter history is not affected by this behavior, samples will be removed from the history by standard rules. Only the reuse of pool samples is affected. This means that the DataWriter history can be empty and the write operation be still blocked because all samples in the pool are unacknowledged.

The chance of the DataWriter blocking on a write operation can be reduced using extra_samples. This will make the pool to allocate more samples than the history size, so that the DataWriter has more chances to get a free sample, while the DataReader can still access samples that have been removed from the DataWriter history.

6.6. Intra-process delivery

eProsima Fast DDS allows to speed up communications between entities within the same process by avoiding any of the overhead involved in the transport layer. Instead, the Publisher directly calls the reception functions of the Subscriber. This not only avoids the copy or send operations of the transport, but also ensures the message is received by the Subscriber, avoiding the acknowledgement mechanism.

This feature is enabled by default, and can be configured using XML profiles (see Intra-process delivery profiles). Currently the following options are available:

  • INTRAPROCESS_OFF: The feature is disabled.

  • INTRAPROCESS_USER_DATA_ONLY: Discovery metadata keeps using ordinary transport.

  • INTRAPROCESS_FULL: Default value. Both user data and discovery metadata using Intra-process delivery.

XML

<library_settings>
    <intraprocess_delivery>FULL</intraprocess_delivery> <!-- OFF | USER_DATA_ONLY | FULL -->
</library_settings>

6.6.1. GUID Prefix considerations for intra-process delivery

Fast DDS utilizes the DomainParticipant’s GuidPrefix_t to identify peers running in the same process. Two participants with identical 8 first bytes on the GuidPrefix_t are considered to be running in the same process, and therefore intra-process delivery is used. is_on_same_process_as() API is provided to check this condition. This mechanism works out-of-the-box when letting Fast DDS set the GUID prefixes for the created DomainParticipants. However, special consideration is required when setting the GuidPrefix_t manually, either programmatically or when using XML.

Important

Fast DDS assigns GUID prefixes considering several host parameters. Among them, the network interfaces enabled. Thus, if at runtime, the network interfaces change, any new DomainParticipant will have a different GUID prefix and will be considered to be running on another host.

eprosima::fastdds::rtps::GuidPrefix_t guid_prefix;
guid_prefix.value[0] = eprosima::fastdds::rtps::octet(0x77);
guid_prefix.value[1] = eprosima::fastdds::rtps::octet(0x73);
guid_prefix.value[2] = eprosima::fastdds::rtps::octet(0x71);
guid_prefix.value[3] = eprosima::fastdds::rtps::octet(0x85);
guid_prefix.value[4] = eprosima::fastdds::rtps::octet(0x69);
guid_prefix.value[5] = eprosima::fastdds::rtps::octet(0x76);
guid_prefix.value[6] = eprosima::fastdds::rtps::octet(0x95);
guid_prefix.value[7] = eprosima::fastdds::rtps::octet(0x66);
guid_prefix.value[8] = eprosima::fastdds::rtps::octet(0x65);
guid_prefix.value[9] = eprosima::fastdds::rtps::octet(0x82);
guid_prefix.value[10] = eprosima::fastdds::rtps::octet(0x82);
guid_prefix.value[11] = eprosima::fastdds::rtps::octet(0x79);

DomainParticipantQos participant_qos;
participant_qos.wire_protocol().prefix = guid_prefix;
// Use modified QoS in the creation of the DomainParticipant entity
participant_ = factory_->create_participant(domain, participant_qos);
DomainParticipantQos participant_qos;
std::istringstream("77.73.71.85.69.76.95.66.65.82.82.79") >> participant_qos.wire_protocol().prefix;
// Use modified QoS in the creation of the DomainParticipant entity
participant_ = factory_->create_participant(domain, participant_qos);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_guidprefix" >
        <rtps>
            <prefix>77.73.71.85.69.76.95.66.65.82.82.79</prefix>
        </rtps>
    </participant>
</profiles>

6.7. TLS over TCP

Warning

This documentation assumes the reader has basic knowledge of TLS concepts since terms like Certificate Authority (CA), Private Key, Rivest–Shamir–Adleman (RSA) cryptosystem, and Diffie-Hellman encryption protocol are not explained in detail.

Fast DDS allows configuring TCP Transports to use TLS (Transport Layer Security). In order to set up TLS, the TCPTransportDescriptor must have its apply_security data member set to true, and its tls_config data member filled with the desired configuration on the TCPTransportDescriptor. The following is an example of configuration of TLS on the TCP server.

DomainParticipantQos qos;

// Create a descriptor for the new transport.
auto tls_transport = std::make_shared<TCPv4TransportDescriptor>();
tls_transport->sendBufferSize = 9216;
tls_transport->receiveBufferSize = 9216;
tls_transport->add_listener_port(5100);

// Create the TLS configuration
using TLSOptions = eprosima::fastdds::rtps::TCPTransportDescriptor::TLSConfig::TLSOptions;
tls_transport->apply_security = true;
tls_transport->tls_config.password = "test";
tls_transport->tls_config.cert_chain_file = "server.pem";
tls_transport->tls_config.private_key_file = "serverkey.pem";
tls_transport->tls_config.tmp_dh_file = "dh2048.pem";
tls_transport->tls_config.add_option(TLSOptions::DEFAULT_WORKAROUNDS);
tls_transport->tls_config.add_option(TLSOptions::SINGLE_DH_USE);
tls_transport->tls_config.add_option(TLSOptions::NO_SSLV2);

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(tls_transport);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <transport_descriptors>
        <transport_descriptor>
            <transport_id>tls_transport_server</transport_id>
            <type>TCPv4</type>
            <tls>
                <password>test</password>
                <private_key_file>serverkey.pem</private_key_file>
                <cert_chain_file>server.pem</cert_chain_file>
                <tmp_dh_file>dh2048.pem</tmp_dh_file>
                <options>
                    <option>DEFAULT_WORKAROUNDS</option>
                    <option>SINGLE_DH_USE</option>
                    <option>NO_SSLV2</option>
                </options>
            </tls>
            <sendBufferSize>9216</sendBufferSize>
            <receiveBufferSize>9216</receiveBufferSize>
            <listening_ports>
                <port>5100</port>
            </listening_ports>
        </transport_descriptor>
    </transport_descriptors>

    <participant profile_name="TLSServerParticipant">
        <rtps>
            <userTransports>
                <transport_id>tls_transport_server</transport_id>
            </userTransports>
        </rtps>
    </participant>
</profiles>

The corresponding configuration on the TCP client is shown in the following example.

DomainParticipantQos qos;

// Set initial peers.
Locator_t initial_peer_locator;
initial_peer_locator.kind = LOCATOR_KIND_TCPv4;
IPLocator::setIPv4(initial_peer_locator, "192.168.1.10");
initial_peer_locator.port = 5100;
qos.wire_protocol().builtin.initialPeersList.push_back(initial_peer_locator);

// Create a descriptor for the new transport.
auto tls_transport = std::make_shared<TCPv4TransportDescriptor>();

// Create the TLS configuration
using TLSOptions = eprosima::fastdds::rtps::TCPTransportDescriptor::TLSConfig::TLSOptions;
using TLSVerifyMode = eprosima::fastdds::rtps::TCPTransportDescriptor::TLSConfig::TLSVerifyMode;
tls_transport->apply_security = true;
tls_transport->tls_config.verify_file = "ca.pem";
tls_transport->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_PEER);
tls_transport->tls_config.add_verify_mode(TLSVerifyMode::VERIFY_FAIL_IF_NO_PEER_CERT);
tls_transport->tls_config.add_option(TLSOptions::DEFAULT_WORKAROUNDS);
tls_transport->tls_config.add_option(TLSOptions::SINGLE_DH_USE);
tls_transport->tls_config.add_option(TLSOptions::NO_SSLV2);
tls_transport->tls_config.server_name = "my_server.com";

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(tls_transport);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <transport_descriptors>
        <transport_descriptor>
            <transport_id>tls_transport_client</transport_id>
            <type>TCPv4</type>
            <tls>
                <verify_file>ca.pem</verify_file>
                <verify_mode>
                    <verify>VERIFY_PEER</verify>
                    <verify>VERIFY_FAIL_IF_NO_PEER_CERT</verify>
                </verify_mode>
                <options>
                    <option>DEFAULT_WORKAROUNDS</option>
                    <option>SINGLE_DH_USE</option>
                    <option>NO_SSLV2</option>
                </options>
                <server_name>my_server.com</server_name>
            </tls>
        </transport_descriptor>
    </transport_descriptors>

    <participant profile_name="TLSClientParticipant">
        <rtps>
            <userTransports>
                <transport_id>tls_transport_client</transport_id>
            </userTransports>
            <builtin>
                <initialPeersList>
                    <locator>
                        <tcpv4>
                            <address>192.168.1.10</address>
                            <physical_port>5100</physical_port>
                        </tcpv4>
                    </locator>
                </initialPeersList>
            </builtin>
        </rtps>
    </participant>
</profiles>

The following table describes the data members that are configurable on TLSConfig.

Member

Data type

Default

Description

password

string

""

Password of the private_key_file or
rsa_private_key_file.

private_key_file

string

""

Path to the private key certificate file.

rsa_private_key_file

string

""

Path to the private key RSA certificate file.

cert_chain_file

string

""

Path to the public certificate chain file.

tmp_dh_file

string

""

Path to the Diffie-Hellman parameters file.

verify_file

string

""

Path to the CA (Certification- Authority) file.

verify_mode

TLSVerifyMode

TLSVerifyMode::UNUSED

Establishes the verification mode mask.
See TLS Verification Mode.

options

TLSOptions

TLSOptions::NONE

Establishes the SSL Context options mask.
See TLS Options.

verify_paths

vector<string>

Empty vector

Paths where the system will look for verification files.

verify_depth

int32_t

-1

Maximum allowed depth for verifying intermediate
certificates.

default_verify_path

bool

false

Look for verification files on the default paths.

handshake_role

TLSHandShakeRole

TLSHandShakeRole::DEFAULT

Role that the transport will take on handshaking.
See TLS Handshake Role.

server_name

string

""

Server name or host name required in case
Server Name Indication (SNI) is used.

Note

Fast DDS uses the Boost.Asio library to handle TLS secure connections. These data members are used to build the asio library context, and most of them are mapped directly into this context without further manipulation. You can find more information about the implications of each member on the Boost.Asio context documentation.

6.7.1. TLS Verification Mode

The verification mode defines how the peer node will be verified. The following table describes the available verification options. Several verification options can be combined in the same TCPTransportDescriptor using the add_verify_mode() member function.

Value

Description

TLSVerifyMode::VERIFY_NONE

Perform no verification.

TLSVerifyMode::VERIFY_PEER

Perform verification of the peer.

TLSVerifyMode::VERIFY_FAIL_IF_NO_PEER_CERT

Fail verification if the peer has no certificate. Ignored unless TLSVerifyMode::VERIFY_PEER is also set.

TLSVerifyMode::VERIFY_CLIENT_ONCE

Do not request client certificate on renegotiation. Ignored unless TLSVerifyMode::VERIFY_PEER is also set.

Note

For a complete description of the different verification modes, please refer to the OpenSSL documentation.

6.7.2. TLS Options

These options define which TLS features are to be supported. The following table describes the available options. Several options can be combined in the same TransportDescriptor using the add_option() member function.

Value

Description

TLSOptions::DEFAULT_WORKAROUNDS

Implement various bug workarounds. See Boost.Asio context.

TLSOptions::NO_COMPRESSION

Disable compression.

TLSOptions::NO_SSLV2

Disable SSL v2.

TLSOptions::NO_SSLV3

Disable SSL v3.

TLSOptions::NO_TLSV1

Disable TLS v1.

TLSOptions::NO_TLSV1_1

Disable TLS v1.1.

TLSOptions::NO_TLSV1_2

Disable TLS v1.2.

TLSOptions::NO_TLSV1_3

Disable TLS v1.3.

TLSOptions::SINGLE_DH_USE

Always create a new key when using Diffie-Hellman parameters.

6.7.3. TLS Handshake Role

The role can take the following values:

Value

Description

TLSHandShakeRole::DEFAULT

Configured as client if connector, and as server if acceptor

TLSHandShakeRole::CLIENT

Configured as client.

TLSHandShakeRole::SERVER

Configured as server.

6.8. Listening Locators

Listening Locators are used to receive incoming traffic on the DomainParticipant. These Locators can be classified according to the communication type and to the nature of the data.

According to the communication type we have:

  • Multicast locators: Listen to multicast communications.

  • Unicast locators: Listen to unicast communications.

According to the nature of the data we have:

  • Metatraffic locators: Used to receive metatraffic information, usually used by built-in endpoints to perform discovery.

  • User locators: Used by the endpoints created by the user to receive user Topic data changes.

Applications can provide their own Listening Locators, or use the Default Listening Locators provided by eProsima Fast DDS.

6.8.1. Adding Listening Locators

Users can add custom Listening Locators to the DomainParticipant using the DomainParticipantQos. Depending on the field where the Locator is added, it will be treated as a multicast, unicast, user or metatraffic Locator.

Note

Both UDP and TCP unicast Locators support to have a null address. In that case, Fast DDS automatically gets and uses local network addresses.

Note

Both UDP and TCP Locators support to have a zero port. In that case, Fast DDS automatically calculates and uses well-known ports for that type of traffic. See Well Known Ports for details about the well-known ports.

Warning

TCP does not support multicast scenarios, so the network architecture must be carefully planned.

6.8.1.1. Metatraffic Multicast Locators

Users can set their own metatraffic multicast locators within the WireProtocolConfigQos: builtin.metatrafficMulticastLocatorList.

DomainParticipantQos qos;

// This locator will open a socket to listen network messages
// on UDPv4 port 22222 over multicast address 239.255.0.1
eprosima::fastdds::rtps::Locator_t locator;
IPLocator::setIPv4(locator, 239, 255, 0, 1);
locator.port = 22222;

// Add the locator to the DomainParticipantQos
qos.wire_protocol().builtin.metatrafficMulticastLocatorList.push_back(locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="CustomMetatrafficMulticastParticipant">
        <rtps>
            <builtin>
                <metatrafficMulticastLocatorList>
                    <!-- LOCATOR_LIST -->
                    <locator>
                        <udpv4>
                            <address>239.255.0.1</address>
                            <port>22222</port>
                        </udpv4>
                    </locator>
                </metatrafficMulticastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>
6.8.1.2. Metatraffic Unicast Locators

Users can set their own metatraffic unicast locators within the WireProtocolConfigQos: builtin.metatrafficUnicastLocatorList.

DomainParticipantQos qos;

// This locator will open a socket to listen network messages
// on UDPv4 port 22223 over address 192.168.0.1
eprosima::fastdds::rtps::Locator_t locator;
IPLocator::setIPv4(locator, 192, 168, 0, 1);
locator.port = 22223;

// Add the locator to the DomainParticipantQos
qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="CustomMetatrafficUnicastParticipant">
        <rtps>
            <builtin>
                <metatrafficUnicastLocatorList>
                    <!-- LOCATOR_LIST -->
                    <locator>
                        <udpv4>
                            <address>192.168.0.1</address>
                            <port>22223</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>
6.8.1.3. User-traffic Multicast Locators

Users can set their own user-traffic multicast locators within the WireProtocolConfigQos: default_multicast_locator_list.

DomainParticipantQos qos;

// This locator will open a socket to listen network messages
// on UDPv4 port 22224 over multicast address 239.255.0.1
eprosima::fastdds::rtps::Locator_t locator;
IPLocator::setIPv4(locator, 239, 255, 0, 1);
locator.port = 22224;

// Add the locator to the DomainParticipantQos
qos.wire_protocol().default_multicast_locator_list.push_back(locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="CustomUsertrafficMulticastParticipant">
        <rtps>
            <defaultMulticastLocatorList>
                <!-- LOCATOR_LIST -->
                <locator>
                    <udpv4>
                        <address>239.255.0.1</address>
                        <port>22224</port>
                    </udpv4>
                </locator>
            </defaultMulticastLocatorList>
        </rtps>
    </participant>
</profiles>
6.8.1.4. User-traffic Unicast Locators

Users can set their own user-traffic unicast locators within the WireProtocolConfigQos: default_unicast_locator_list.

DomainParticipantQos qos;

// This locator will open a socket to listen network messages
// on UDPv4 port 22225 over address 192.168.0.1
eprosima::fastdds::rtps::Locator_t locator;
IPLocator::setIPv4(locator, 192, 168, 0, 1);
locator.port = 22225;

// Add the locator to the DomainParticipantQos
qos.wire_protocol().default_unicast_locator_list.push_back(locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="CustomUsertrafficUnicastParticipant">
        <rtps>
            <defaultUnicastLocatorList>
                <!-- LOCATOR_LIST -->
                <locator>
                    <udpv4>
                        <address>192.168.0.1</address>
                        <port>22225</port>
                    </udpv4>
                </locator>
            </defaultUnicastLocatorList>
        </rtps>
    </participant>
</profiles>

6.8.2. Default Listening Locators

If the application does not define any Listening Locators, eProsima Fast DDS automatically enables a set of listening UDPv4 locators by default. This allows out-of-the-box communication in most cases, without the need of further configuring the Transport Layer.

  • If the application does not define any metatraffic Locator (neither unicast nor multicast), Fast DDS enables one multicast Locator that will be used during Discovery, and one unicast Locator that will be used for peer-to-peer communication with already discovered DomainParticipants.

  • If the application does not define any user-traffic Locator (neither unicast nor multicast), Fast DDS enables one unicast Locator that will be used for peer-to-peer communication of Topic data.

  • If the application does not define any participantId, Fast DDS will use the value given by the DomainParticipantFactory, which will try always to provide the lowest available value per DomainParticipantFactory (per process).

For example, it is possible to prevent multicast traffic adding a single metatraffic unicast Locator as described in Disabling all Multicast Traffic.

Default Listening Locators always use Well Known Ports.

6.8.3. Well Known Ports

The DDSI-RTPS V2.2 standard (Section 9.6.1.1) defines a set of rules to calculate well-known ports for default Locators, so that DomainParticipants can communicate with these default Locators. Well-known ports are also selected automatically by Fast DDS when a Locator is configured with port number 0.

Well-known ports are calculated using the following predefined rules:

Rules to calculate ports on default listening locators

Traffic type

Well-known port expression

Metatraffic multicast

PB + DG * domainId + offsetd0

Metatraffic unicast

PB + DG * domainId + offsetd1 + PG * participantId

User multicast

PB + DG * domainId + offsetd2

User unicast

PB + DG * domainId + offsetd3 + PG * participantId

Discovery Server (Easy Mode)

PB + DG * domainId + offsetd4

The values used in these rules are explained on the following table. The default values can be modified using the port member of the WireProtocolConfigQos on the DomainParticipantQos.

Note

Deployments where multiple DomainParticipants are created within the same host can lead into denying available ports for them if the amount of DomainParticipants created reaches the value of BuiltinAttributes::mutation_tries (100 by default). When that happens, the DomainParticipants will not be able to create the listening ports (this is notified with a log warning) and will be created without unicast locators configured.

Refer to this example for configuring both the mutation_tries values.

Values used in the rules to calculate well-known ports

Symbol

Meaning

Default value

QoS field

DG

DomainID gain

250

wire_protocol().port.domainIDGain

PG

ParticipantId gain

2

wire_protocol().port.participantIDGain

PB

Port Base number

7400

wire_protocol().port.portBase

offsetd0

Additional offset

0

wire_protocol().port.offsetd0

offsetd1

Additional offset

10

wire_protocol().port.offsetd1

offsetd2

Additional offset

1

wire_protocol().port.offsetd2

offsetd3

Additional offset

11

wire_protocol().port.offsetd3

offsetd4

Additional offset

2

wire_protocol().port.offsetd4

6.9. Announced Locators

In order for communication to take place, DDS entities need to exchange the list of addresses and ports where they can be reached. Apart from the default announced locators, which correspond to addresses of the interfaces in the host where the application is running, the user can configure additional locators with addresses and ports on other networks, when routing rules have been correspondingly set up.

6.9.1. Default Announced Locators

The default list of announced locators will be constructed from the listening locators, as follows:

  • If the address field of the locator is a null address (i.e. 0.0.0.0 for UDPv4), a locator of the same kind and port will be announced for each of the addresses of the network interfaces of the host.

  • If the address field of the locator is not a null address, a single locator with that address will be announced.

6.9.2. External Locators

The user can configure a set of external locators for each of the lists of unicast locators:

An external locator is made up of the standard locator fields (kind, address, and port), plus the following attributes:

  • An externality that indicates the number of hops from the host where the application is running to the LAN represented by the external locator.

  • A cost indicating the communication cost relative to other locators on the same externality level.

  • A mask with the number of significant bits on the LAN represented by the external locator.

6.9.2.1. Externality levels

The main purpose of the external locators is to enable communication across different levels of interconnected LANs. Communication will be performed using the locators of the innermost LAN available.

As an example, consider a network topology where the application is running on a host connected to a LAN of an office, which in turn connects to a LAN for all the offices in the same floor, which in turn connects to a LAN for the building.

With the default configuration, communication will only occur between hosts on the LAN for the office. This is considered the externality level 0, which is reserved for the LANs directly connected to the network interfaces of the host where the application is running. This is the externality level that will be used on the matching algorithm for the default announced locators. The floor LAN will be configured as externality level 1, whereas the building LAN will be configured as externality level 2.

Note that in order for the communication to be successful, routing rules should most probably need to be added to the different network routers.

Important

Externality level 0 is automatically populated by Fast DDS and cannot be configured by the application.

6.9.2.2. Matching algorithm

When a remote entity is discovered, its list of announced locators is processed to select the ones on the innermost externality level where the communication can be established. The highest externality level is checked first.

If the discovered addresses for one level are equal to the ones announced by the local entity, it means they are on the same host at that level, and the algorithm proceeds to an inner level. If the discovered addresses are not equal to the ones announced by the local entity, processing stops at the current level.

When the externality level on which the communication will be established has been decided, the algorithm will:

  • Remove locators that match with addresses on any other externality level.

  • Keep locators that match with the selected externality level.

  • For the locators with an address that does not match with any of the locators announced by the local entity:

    • Keep them when ignore_non_matching_locators is false (default behavior)

    • Remove them when ignore_non_matching_locators is true

6.9.2.3. Additional considerations

Since using external locators increases the number of locators announced, the allocation limits for locators discovery would need to be adjusted for your application.

Participants running on the same host, but using different addresses on their builtin.metatraffic_external_unicast_locators will discard shared memory transport locators. Data sharing communication is not affected by this limitation.

Warning

Interface whitelist will be deprecated in future versions of Fast DDS. The use of the new interfaces allowlist is recommended.

6.10. Interface Whitelist

Using Fast DDS, it is possible to limit the network interfaces used by TCP Transport and UDP Transport. This is achieved by adding the interfaces to the interfaceWhiteList field in the TCPTransportDescriptor or UDPTransportDescriptor. Thus, the communication interfaces used by the DomainParticipants whose TransportDescriptorInterface defines an interfaceWhiteList is limited to the interfaces’ addresses defined in that list, therefore avoiding the use of the rest of the network interfaces available in the system. The interfaces in interfaceWhiteList can be specified both by IP address or interface name. For example:

  • Interface whitelist filled with IP address:

    DomainParticipantQos qos;
    
    // Create a descriptor for the new transport.
    auto tcp_transport = std::make_shared<TCPv4TransportDescriptor>();
    
    // Add loopback to the whitelist by IP address
    tcp_transport->interfaceWhiteList.emplace_back("127.0.0.1");
    
    // Link the Transport Layer to the Participant.
    qos.transport().user_transports.push_back(tcp_transport);
    
    // Avoid using the builtin transports
    qos.transport().use_builtin_transports = false;
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <profiles xmlns="http://www.eprosima.com">
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>CustomTcpTransportWhitelistAddress</transport_id>
                <type>TCPv4</type>
                <interfaceWhiteList>
                    <address>127.0.0.1</address>
                </interfaceWhiteList>
            </transport_descriptor>
        </transport_descriptors>
    
        <participant profile_name="CustomTcpTransportWhitelistAddressParticipant">
            <rtps>
                <useBuiltinTransports>false</useBuiltinTransports>
                <userTransports>
                    <transport_id>CustomTcpTransportWhitelistAddress</transport_id>
                </userTransports>
            </rtps>
        </participant>
    </profiles>
    
  • Interface whitelist filled with interface names:

    DomainParticipantQos qos;
    
    // Create a descriptor for the new transport.
    auto tcp_transport = std::make_shared<TCPv4TransportDescriptor>();
    
    // Add loopback to the whitelist by interface name
    tcp_transport->interfaceWhiteList.emplace_back("lo");
    
    // Link the Transport Layer to the Participant.
    qos.transport().user_transports.push_back(tcp_transport);
    
    // Avoid using the builtin transports
    qos.transport().use_builtin_transports = false;
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <profiles xmlns="http://www.eprosima.com">
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>CustomTcpTransportWhitelistName</transport_id>
                <type>TCPv4</type>
                <interfaceWhiteList>
                    <interface>lo</interface>
                </interfaceWhiteList>
            </transport_descriptor>
        </transport_descriptors>
    
        <participant profile_name="CustomTcpTransportWhitelistNameParticipant">
            <rtps>
                <useBuiltinTransports>false</useBuiltinTransports>
                <userTransports>
                    <transport_id>CustomTcpTransportWhitelistName</transport_id>
                </userTransports>
            </rtps>
        </participant>
    </profiles>
    

Important

If none of the values in the transport descriptor’s whitelist match the interfaces on the host, then all the interfaces in the whitelist are filtered out and therefore no communication will be established through that transport.

Warning

The interface whitelist feature applies to network interfaces. Therefore, it is only available on TCP Transport and UDP Transport.

Warning

The configuration options described in this section apply to network interfaces. Therefore, it is only available on TCP Transport and UDP Transport.

6.11. Interfaces configuration

By default, Fast DDS makes use of all active network interfaces found in the system to communicate (note: applies to UDP Transport and TCP Transport). However, it is possible for a user to indicate a specific set of network interfaces to be used by the library, and/or configure some of them in a specific manner.

6.11.1. Netmask filtering

The standard behaviour in Fast-DDS is to attempt data transmission to any remote locator for which a compatible transport (based on kind) is registered. This may result in a non-optimum resource utilization, as messages could be sent from an interface to an unreachable destination given a particular network architecture. In this situation, a user may decide to enable the netmask filtering feature, which would prevent this behavior by only sending data from a network interface to remote locators within the same subnetwork.

This configuration option can be set at participant, transport and interface levels, and its possible values are:

Value

Description

ON

Enable netmask filtering.

OFF

Disable netmask filtering.

AUTO

Use container’s netmask filter configuration.

An AUTO netmask filter configuration means that its effective value will be given by that of its “container”, which in the case of an allowlist entry would be the transport descriptor where it is included, and in the case of a transport descriptor would be the participant where it is registered.

However not all configurations are valid; this is, for example, a transport’s netmask filter configuration cannot be OFF if it is ON for the participant where this transport is registered. Likewise, the netmask filter configuration for an allowlist entry cannot be ON if it is OFF for the transport descriptor where this allowlist is defined.

Note

Due to implementation details, it is required to set ignore_non_matching_locators to true (see Matching algorithm) both in participants and endpoints when enabling the netmask filtering feature at participant or transport level without defining an allowlist or blocklist.

Additional considerations need to be taken into account when using netmask filtering in combination with external locators. In particular, it is not possible to enable netmask filtering in all entries of an allowlist when a set of local external locators (with an externality greater than 0) is defined for a participant or endpoint. The reason for this is that a matching remote external locator would then (most likely) be effectively ignored, as no network interface would be able to reach it according to its network mask.

Netmask filtering can be enabled at participant level both via C++ API or XML configuration:

// Configure netmask filtering at participant level
qos.transport().netmask_filter = NetmaskFilterKind::AUTO;
qos.wire_protocol().ignore_non_matching_locators = true; // Required if not defining an allowlist or blocklist
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
    <participant profile_name="CustomTcpParticipantNetmaskFilterParticipant">
        <rtps>
            <ignore_non_matching_locators>true</ignore_non_matching_locators>
            <netmask_filter>ON</netmask_filter>
        </rtps>
    </participant>
</profiles>

For socket (UDP/TCP) transport descriptors:

// Create a descriptor for the new transport.
auto udp_transport = std::make_shared<UDPv4TransportDescriptor>();

// Configure netmask filtering at transport level
udp_transport->netmask_filter = NetmaskFilterKind::AUTO;
qos.wire_protocol().ignore_non_matching_locators = true; // Required if not defining an allowlist or blocklist
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
    <transport_descriptors>
        <transport_descriptor>
            <transport_id>CustomTcpTransportNetmaskFilter</transport_id>
            <type>TCPv4</type>
            <netmask_filter>ON</netmask_filter>
        </transport_descriptor>
    </transport_descriptors>

    <participant profile_name="CustomTcpTransportNetmaskFilterParticipant">
        <rtps>
            <useBuiltinTransports>false</useBuiltinTransports>
            <userTransports>
                <transport_id>CustomTcpTransportNetmaskFilter</transport_id>
            </userTransports>
            <ignore_non_matching_locators>true</ignore_non_matching_locators>
        </rtps>
    </participant>
</profiles>

See Allowlist to learn how to configure netmask filtering for specific network devices.

6.11.2. Allowlist

Using Fast DDS, it is possible to limit the network interfaces used by TCP Transport and UDP Transport. This is achieved by adding the interfaces to the allowlist field in the TCPTransportDescriptor or UDPTransportDescriptor. Thus, the communication interfaces used by the DomainParticipants whose TransportDescriptorInterface defines an allowlist is limited to the interfaces defined in that list, therefore avoiding the use of the rest of the network interfaces available in the system. The interfaces in allowlist can be specified both by IP address or interface name. Additionally, each entry added to the allowlist may specify a netmask filter configuration value (AUTO by default).

For example:

DomainParticipantQos qos;

// Create a descriptor for the new transport.
auto udp_transport = std::make_shared<UDPv4TransportDescriptor>();

// Add allowed interface by device name
udp_transport->interface_allowlist.emplace_back("eth0", NetmaskFilterKind::OFF);

// Add allowed interface by IP address (using default netmask filter AUTO)
udp_transport->interface_allowlist.emplace_back("127.0.0.1");

// Add allowed interface with explicit AllowedNetworkInterface construction
AllowedNetworkInterface another_allowed_interface("docker0", NetmaskFilterKind::OFF);
udp_transport->interface_allowlist.emplace_back(another_allowed_interface);

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(udp_transport);

// Avoid using the builtin transports
qos.transport().use_builtin_transports = false;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
    <transport_descriptors>
        <transport_descriptor>
            <transport_id>CustomTcpTransportAllowlist</transport_id>
            <type>TCPv4</type>
            <interfaces>
                <allowlist>
                    <interface name="wlp59s0" netmask_filter="ON"/>
                    <interface name="192.168.1.10" netmask_filter="OFF"/>
                </allowlist>
            </interfaces>
        </transport_descriptor>
    </transport_descriptors>

    <participant profile_name="CustomTcpTransportAllowlistParticipant">
        <rtps>
            <useBuiltinTransports>false</useBuiltinTransports>
            <userTransports>
                <transport_id>CustomTcpTransportAllowlist</transport_id>
            </userTransports>
        </rtps>
    </participant>
</profiles>

Important

If none of the values in the transport descriptor’s allowlist match the interfaces on the host, then all the interfaces in the allowlist are filtered out and therefore no communication will be established through that transport.

6.11.3. Blocklist

Apart from defining a list of allowed interfaces, it is also possible to define a list of interfaces that should be blocked. This is accomplished through the blocklist field present in the TCPTransportDescriptor or UDPTransportDescriptor.

Note

This list takes precedence over the allowlist, so if a network interface is in both lists, it will be blocked.

The interfaces in blocklist can be specified both by IP address or interface name.

For example:

DomainParticipantQos qos;

// Create a descriptor for the new transport.
auto udp_transport = std::make_shared<UDPv4TransportDescriptor>();

// Add blocked interface by device name
udp_transport->interface_blocklist.emplace_back("docker0");

// Add blocked interface by IP address
udp_transport->interface_blocklist.emplace_back("127.0.0.1");

// Add blocked interface with explicit BlockedNetworkInterface construction
BlockedNetworkInterface another_blocked_interface("eth0");
udp_transport->interface_blocklist.emplace_back(another_blocked_interface);

// Link the Transport Layer to the Participant.
qos.transport().user_transports.push_back(udp_transport);

// Avoid using the builtin transports
qos.transport().use_builtin_transports = false;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
    <transport_descriptors>
        <transport_descriptor>
            <transport_id>CustomTcpTransportBlocklist</transport_id>
            <type>TCPv4</type>
            <interfaces>
                <blocklist>
                    <interface name="127.0.0.1"/>
                    <interface name="docker0"/>
                </blocklist>
            </interfaces>
        </transport_descriptor>
    </transport_descriptors>

    <participant profile_name="CustomTcpTransportBlocklistParticipant">
        <rtps>
            <useBuiltinTransports>false</useBuiltinTransports>
            <userTransports>
                <transport_id>CustomTcpTransportBlocklist</transport_id>
            </userTransports>
        </rtps>
    </participant>
</profiles>

6.12. Disabling all Multicast Traffic

If all the peers are known beforehand and have been configured on the Initial Peers List, all multicast traffic can be completely disabled.

By defining a custom Metatraffic Unicast Locators, the local DomainParticipant creates a unicast meta traffic receiving resource for each address-port pair specified in the list, avoiding the creation of the default metatraffic multicast and unicast locators. This prevents the DomainParticipant from listening to any discovery data from multicast sources.

Consideration should be given to the assignment of the ports in the metatrafficUnicastLocatorList, avoiding the assignment of ports that are not available or do not match the address-port listed in the publisher participant Initial Peers List.

The following is an example of how to disable all multicast traffic configuring one metatraffic unicast locator.

DomainParticipantQos qos;

// Metatraffic Multicast Locator List will be empty.
// Metatraffic Unicast Locator List will contain one locator, with null address and null port.
// Then Fast DDS will use all network interfaces to receive network messages using a well-known port.
Locator_t default_unicast_locator;
qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(default_unicast_locator);

// Initial peer will be UDPv4 address 192.168.0.1. The port will be a well-known port.
// Initial discovery network messages will be sent to this UDPv4 address.
Locator_t initial_peer;
IPLocator::setIPv4(initial_peer, 192, 168, 0, 1);
qos.wire_protocol().builtin.initialPeersList.push_back(initial_peer);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="disable_multicast" is_default_profile="true">
        <rtps>
            <builtin>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>192.168.0.1</address>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
                <initialPeersList>
                    <locator>
                        <udpv4>
                            <address>192.168.0.1</address>
                        </udpv4>
                    </locator>
                </initialPeersList>
            </builtin>
        </rtps>
    </participant>
</profiles>

7. Persistence Service

Using default QoS, the DataWriter history is only available for DataReader throughout the DataWriter’s life. This means that the history does not persist between DataWriter initializations and therefore it is on an empty state on DataWriter creation. Similarly, the DataReader history does not persist the DataReader’s life, thus also being empty on DataReader creation. However, eProsima Fast DDS offers the possibility to configure the DataWriter’s history to be stored in a persistent database, so that the DataWriter can load its history from it on creation. Furthermore, DataReaders can be configured to store the last notified change in the database, so that they can recover their state on creation.

This mechanism allows recovering a previous state on starting the Data Distribution Service, thus adding robustness to applications in the case of, for example, unexpected shutdowns. Configuring the persistence service, DataWriters and DataReaders can resume their operation from the state in which they were when the shutdown occurred.

Note

Mind that DataReaders do not store their history into the database, but rather the last notified change from the DataWriter. This means that they will resume operation where they left, but they will not have the previous information, since that was already notified to the application.

7.1. Configuration

The configuration of the persistence service is accomplished by setting of the appropriate DataWriter and DataReader DurabilityQosPolicy, and by specifying the suitable properties for each entity’s (DomainParticipant, DataWriter, or DataReader) PropertyPolicyQos.

  • For the Persistence Service to have any effect, the DurabilityQosPolicyKind needs to be set to TRANSIENT_DURABILITY_QOS or PERSISTENT_DURABILITY_QOS.

  • A persistence identifier (Guid_t) must be set for the entity using the property dds.persistence.guid. This identifier is used to load the appropriate data from the database, and also to synchronize DataWriter and DataReader between restarts. The GUID consists of 16 bytes separated into two groups:

    The persistence identifier is specified using a string of 12 dot-separated bytes, expressed in hexadecimal base, followed by a vertical bar separator (|) and another 4 dot-separated bytes, also expressed in hexadecimal base (see Example). For selecting an appropriate GUID for the DataReader and DataWriter, please refer to RTPS standard (section 9.3.1 The Globally Unique Identifier (GUID)).

    If no dds.persistence.guid is specified, the durability behavior will fallback to TRANSIENT_LOCAL_DURABILITY_QOS.

  • A persistence plugin must be configured for managing the database using property dds.persistence.plugin (see PERSISTENCE:SQLITE3 built-in plugin):

7.2. PERSISTENCE:SQLITE3 built-in plugin

This plugin provides persistence through a local database file using SQLite3 API. To activate the plugin, dds.persistence.plugin property must be added to the PropertyPolicyQos of the DomainParticipant, DataWriter, or DataReader with value builtin.SQLITE3. Furthermore, dds.persistence.sqlite3.filename property must be added to the entities PropertyPolicyQos, specifying the database file name. These properties are summarized in the following table:

Persistence::SQLITE3 configuration properties

Property name

Property value

dds.persistence.plugin

builtin.SQLITE3

dds.persistence.sqlite3.filename

Name of the file used for persistent storage.
Default value: persistence.db

Note

To avoid undesired delays caused by concurrent access to the SQLite3 database, it is advisable to specify a different database file for each DataWriter and DataReader.

Important

The plugin set in the PropertyPolicyQos of DomainParticipant only applies if that of the DataWriter/DataReader does no exist or is invalid.

7.3. Example

This example shows how to configure the persistence service using PERSISTENCE:SQLITE3 built-in plugin plugin both from C++ and using eProsima Fast DDS XML profile files (see XML profiles).

/*
 * In order for this example to be self-contained, all the entities are created programatically, including the data
 * type and type support. This has been done using Fast DDS Dynamic Types API, but it could be substituted with a
 * Fast DDS-Gen generated type support if an IDL file is available. The Dynamic Type created here is the equivalent
 * of the following IDL:
 *
 *     struct persistence_topic_type
 *     {
 *         unsigned long index;
 *         string message;
 *     };
 */

// Configure persistence service plugin for DomainParticipant
DomainParticipantQos pqos;
pqos.properties().properties().emplace_back("dds.persistence.plugin", "builtin.SQLITE3");
pqos.properties().properties().emplace_back("dds.persistence.sqlite3.filename", "persistence.db");
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, pqos);

/********************************************************************************************************
* CREATE TYPE AND TYPE SUPPORT
*********************************************************************************************************
* This part could be replaced if IDL file and Fast DDS-Gen are available.
* The type is created with name "persistence_topic_type"
* Additionally, create a data object and populate it, just to show how to do it
********************************************************************************************************/
// Create a struct builder for a type with name "persistence_topic_type"
const std::string topic_type_name = "persistence_topic_type";

TypeDescriptor::_ref_type struct_type_descriptor {traits<TypeDescriptor>::make_shared()};
struct_type_descriptor->kind(TK_STRUCTURE);
struct_type_descriptor->name(topic_type_name);
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(struct_type_descriptor)};

// The type consists of two members, and index and a message. Add members to the struct.
MemberDescriptor::_ref_type index_member_descriptor {traits<MemberDescriptor>::make_shared()};
index_member_descriptor->name("index");
index_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                get_primitive_type(TK_UINT32));
struct_builder->add_member(index_member_descriptor);

MemberDescriptor::_ref_type message_member_descriptor {traits<MemberDescriptor>::make_shared()};
message_member_descriptor->name("message");
message_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                create_string_type(static_cast<uint32_t>(LENGTH_UNLIMITED))->build());
struct_builder->add_member(message_member_descriptor);

// Build the type
DynamicType::_ref_type struct_type {struct_builder->build()};

// Create type support and register the type
TypeSupport type_support(new DynamicPubSubType(struct_type));
type_support.register_type(participant);

// Create data sample a populate data. This is to be used when calling `writer->write()`
DynamicData::_ref_type dyn_helloworld {DynamicDataFactory::get_instance()->create_data(struct_type)};

dyn_helloworld->set_uint32_value(0, 0);
dyn_helloworld->set_string_value(1, "HelloWorld");
/********************************************************************************************************
* END CREATE TYPE AND TYPE SUPPORT
********************************************************************************************************/

// Create a topic
Topic* topic = participant->create_topic("persistence_topic_name", topic_type_name, TOPIC_QOS_DEFAULT);

// Create a publisher and a subscriber with default QoS
Publisher* publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT, nullptr);
Subscriber* subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr);

// Configure DataWriter's durability and persistence GUID so it can use the persistence service
DataWriterQos dwqos = DATAWRITER_QOS_DEFAULT;
dwqos.durability().kind = TRANSIENT_DURABILITY_QOS;
dwqos.properties().properties().emplace_back("dds.persistence.guid",
        "77.72.69.74.65.72.5f.70.65.72.73.5f|67.75.69.64");
DataWriter* writer = publisher->create_datawriter(topic, dwqos);

// Configure DataReaders's durability and persistence GUID so it can use the persistence service
DataReaderQos drqos = DATAREADER_QOS_DEFAULT;
drqos.durability().kind = TRANSIENT_DURABILITY_QOS;
drqos.properties().properties().emplace_back("dds.persistence.guid",
        "72.65.61.64.65.72.5f.70.65.72.73.5f|67.75.69.64");
DataReader* reader = subscriber->create_datareader(topic, drqos);
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <!-- DomainParticipant configuration -->
        <participant profile_name="persistence_service_participant">
            <rtps>
                <propertiesPolicy>
                    <properties>
                        <!-- Select persistence plugin -->
                        <property>
                            <name>dds.persistence.plugin</name>
                            <value>builtin.SQLITE3</value>
                        </property>
                        <!-- Database file name -->
                        <property>
                            <name>dds.persistence.sqlite3.filename</name>
                            <value>persistence_service.db</value>
                        </property>
                    </properties>
                </propertiesPolicy>
            </rtps>
        </participant>

        <!-- DataWriter configuration -->
        <data_writer profile_name="persistence_service_data_writer">
            <qos>
                <!-- Set durability to TRANSIENT_DURABILITY_QOS -->
                <durability>
                    <kind>TRANSIENT</kind>
                </durability>
            </qos>
            <propertiesPolicy>
                <properties>
                    <!-- Persistence GUID -->
                    <property>
                        <name>dds.persistence.guid</name>
                        <value>77.72.69.74.65.72.5f.70.65.72.73.5f|67.75.69.64</value>
                    </property>
                </properties>
            </propertiesPolicy>
        </data_writer>

        <data_reader profile_name="persistence_service_data_reader">
            <qos>
                <!-- Set durability to TRANSIENT_DURABILITY_QOS -->
                <durability>
                    <kind>TRANSIENT</kind>
                </durability>
            </qos>
            <propertiesPolicy>
                <properties>
                    <!-- Persistence GUID -->
                    <property>
                        <name>dds.persistence.guid</name>
                        <value>72.65.61.64.65.72.5f.70.65.72.73.5f|67.75.69.64</value>
                    </property>
                </properties>
            </propertiesPolicy>
        </data_reader>
    </profiles>
</dds>

Note

For instructions on how to create DomainParticipants, DataReaders, and DataWriters, please refer to Profile based creation of a DomainParticipant, Profile based creation of a DataWriter, and Profile based creation of a DataReader respectively.

8. Security

The DDS Security specification includes five security builtin plugins.

  1. Authentication plugin: DDS:Auth:PKI-DH. This plugin provides authentication for each DomainParticipant joining a DDS Domain using a trusted Certificate Authority (CA). Support mutual authentication between DomainParticipants and establish a shared secret.

  2. Access Control plugin: DDS:Access:Permissions. This plugin provides access control to DomainParticipants which perform protected operations.

  3. Cryptographic plugin: DDS:Crypto:AES-GCM-GMAC. This plugin provides authenticated encryption using Advanced Encryption Standard (AES) in Galois Counter Mode (AES-GCM).

  4. Logging plugin: DDS:Logging:DDS_LogTopic. This plugin logs security events.

  5. Data Tagging: DDS:Tagging:DDS_Discovery. This plugin enables the addition of security labels to the data. Thus it is possible to specify classification levels of the data. In the DDS context it can be used as a complement to access control, creating an access control based on data tagging; for message prioritization; and to prevent its use by the middleware to be used instead by the application or service.

Note

Currently the DDS:Tagging:DDS_Discovery plugin is not implemented in Fast DDS. Its implementation is expected for future release of Fast DDS.

In compliance with the DDS Security specification, Fast DDS provides secure communication by implementing pluggable security at three levels: a) DomainParticipants authentication (DDS:Auth:PKI-DH), b) access control of Entities (DDS:Access:Permissions), and c) data encryption (DDS:Crypto:AES-GCM-GMAC). Furthermore, for the monitoring of the security plugins and logging relevant events, Fast DDS implements the logging plugin (DDS:Logging:DDS_LogTopic).

By default, Fast DDS does not compile any security support, but it can be activated adding -DSECURITY=ON at CMake configuration step. For more information about Fast DDS compilation, see Linux installation from sources and Windows installation from sources.

Security plugins can be activated through the DomainParticipantQos properties. A Property is defined by its name (std::string) and its value (std::string).

Warning

For the full understanding of this documentation it is required the user to have basic knowledge of network security since terms like Certificate Authority (CA), Public Key Infrastructure (PKI), and Diffie-Hellman encryption protocol are not explained in detail. However, it is possible to configure basic system security settings, i.e. authentication, access control and encryption, to Fast DDS without this knowledge.

Warning

The use of security plugins is incompatible with Data-sharing delivery.

The following sections describe how to configure each of these properties to set up the Fast DDS security plugins.

8.1. Authentication plugin: DDS:Auth:PKI-DH

This is the starting point for all the security mechanisms. The authentication plugin provides the mechanisms and operations required for DomainParticipants authentication at discovery. If the security module was activated at Fast DDS compilation, when a DomainParticipant is either locally created or discovered, it needs to be authenticated in order to be able to communicate in a DDS Domain. Therefore, when a DomainParticipant detects a remote DomainParticipant, both try to authenticate themselves using the activated authentication plugin. If the authentication process finishes successfully both DomainParticipant match and the discovery mechanism continues. On failure, the remote DomainParticipant is rejected.

The authentication plugin implemented in Fast DDS is referred to as “DDS:Auth:PKI-DH”, in compliance with the DDS Security specification. The DDS:Auth:PKI-DH plugin uses a trusted Certificate Authority (CA) and the ECDSA Digital Signature Algorithms to perform the mutual authentication. It also establishes a shared secret using either Elliptic Curve Diffie-Hellman (ECDH) or MODP-2048 Diffie-Hellman (DH) as Key Agreement protocol. This shared secret can be used by other security plugins as Cryptographic plugin: DDS:Crypto:AES-GCM-GMAC.

The DDS:Auth:PKI-DH authentication plugin, can be activated setting the DomainParticipantQos properties() dds.sec.auth.plugin with the value builtin.PKI-DH. The following table outlines the properties used for the DDS:Auth:PKI-DH plugin configuration.

Property name

Property value

identity_ca

URI to the X.509 v3 certificate of the Identity CA in PEM format.
Supported URI schemes: file.

identity_certificate

URI to an X.509 v3 certificate signed by the Identity CA in PEM format
containing the signed public key for the Participant.
Supported URI schemes: file.

identity_crl (optional)

URI to a X.509 Certificate Revocation List (CRL).
Supported URI schemes: file.

private_key

URI to access the private Private Key for the Participant.
Supported URI schemes: file, PKCS#11.

password (optional)

A password used to decrypt the private_key.
If the password property is not present, then the value supplied in the
private_key property must contain the decrypted private key.
The password property is ignored if the private_key is given in PKCS#11 scheme.

preferred_key_agreement (optional)

The preferred algorithm to use for generating the session’s shared secret
at the end of the authentication phase. Supported values are:
a) DH, DH+MODP-2048-256 for Diffie-Hellman Ephemeral with 2048-bit MODP Group parameters.
b) ECDH, ECDH+prime256v1-CEUM for Elliptic Curve Diffie-Hellman Ephemeral with the NIST P-256 curve.
c) AUTO for selecting the key agreement based on the signature algorithm in the Identity CA’s certificate.
Will default to AUTO if the property is not present.

transmit_algorithms_as_legacy (optional)

Whether to transmit algorithm identifiers in non-standard legacy format.
Will default to false if the property is not present.

Note

All listed properties have “dds.sec.auth.builtin.PKI-DH.” prefix. For example: dds.sec.auth.builtin.PKI-DH.identity_ca.

The following is an example of how to set the properties of DomainParticipantQoS for the DDS:Auth:PKI-DH plugin configuration.

DomainParticipantQos pqos;

// Activate DDS:Auth:PKI-DH plugin
pqos.properties().properties().emplace_back("dds.sec.auth.plugin",
        "builtin.PKI-DH");

// Configure DDS:Auth:PKI-DH plugin
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.identity_ca",
    "file://maincacert.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.identity_certificate",
    "file://partcert.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.identity_crl",
    "file://crl.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.private_key",
    "file://partkey.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.password",
    "domainParticipantPassword");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.preferred_key_agreement",
    "ECDH");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.transmit_algorithms_as_legacy",
    "true");
<participant profile_name="secure_domainparticipant_conf_auth_plugin_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Activate DDS:Auth:PKI-DH plugin -->
                <property>
                    <name>dds.sec.auth.plugin</name>
                    <value>builtin.PKI-DH</value>
                </property>
                <!-- Configure DDS:Auth:PKI-DH plugin -->
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.identity_ca</name>
                    <value>file://maincacert.pem</value>
                </property>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.identity_certificate</name>
                    <value>file://partcert.pem</value>
                </property>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.identity_crl</name>
                    <value>file://crl.pem</value>
                </property>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.private_key</name>
                    <value>file://partkey.pem</value>
                </property>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.password</name>
                    <value>domainParticipantPassword</value>
                </property>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.preferred_key_agreement</name>
                    <value>ECDH</value>
                </property>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.transmit_algorithms_as_legacy</name>
                    <value>true</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>

8.1.1. Generation of X.509 certificates

An X.509 digital certificate is a document that has been encrypted and/or digitally signed according to RFC 5280. The X.509 certificate refers to the Public Key Infrastructure (PKI) certificate of the IETF , and specifies the standard formats for public-key certificates and a certification route validation algorithm. A simple way to generate these certificates for a proprietary PKI structure is through the OpenSSL toolkit. This section explains how to build a certificate infrastructure from the trusted CA certificate to the end-entity certificate, i.e. the DomainParticipant.

8.1.1.1. Generating the CA certificate for self-signing

First, since multiple certificates will need to be issued, one for each of the DomainParticipants, a dedicated CA is set up, and the CA’s certificate is installed as the root key of all DomainParticipants. Thus, the DomainParticipants will accept all certificates issued by our own CA. To create a proprietary CA certificate, a configuration file must first be written with the CA information. An example of the CA configuration file is shown below. The OpenSSL commands shown in this example are compatible with both Linux and Windows Operating Systems (OS). However, all other commands are only compatible with Linux OS.

# File: maincaconf.cnf
# OpenSSL example Certificate Authority configuration file

####################################################################
[ ca ]
default_ca = CA_default # The default ca section

####################################################################
[ CA_default ]

dir = . # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
unique_subject = no # Set to 'no' to allow creation of
                    # several ctificates with same subject.
new_certs_dir = $dir

certificate = $dir/maincacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
                           # must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/maincakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file

name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options

default_days= 1825 # how long to certify for
default_crl_days = 30 # how long before next CRL
default_md = sha256 # which md to use.
preserve = no # keep passed DN ordering

policy = policy_match

# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
prompt = no
#default_bits = 1024
#default_keyfile = privkey.pem
distinguished_name= req_distinguished_name
#attributes = req_attributes
#x509_extensions = v3_ca # The extentions to add to the self signed cert
string_mask = utf8only

[ req_distinguished_name ]
countryName = ES
stateOrProvinceName = MA
localityName = Tres Cantos
0.organizationName = eProsima
commonName = eProsima Main Test CA
emailAddress = mainca@eprosima.com

After writing the configuration file, next commands generate the certificate using the Elliptic Curve Digital Signature Algorithm (ECDSA).

openssl ecparam -name prime256v1 > ecdsaparam

openssl req -nodes -x509 \
  -days 3650 \
  -newkey ec:ecdsaparam \
  -keyout maincakey.pem \
  -out maincacert.pem \
  -config maincaconf.cnf
8.1.1.2. Generating the DomainParticipant certificate

As was done for the CA, a DomainParticipant certificate configuration file needs to be created first.

# File: partconf.cnf

prompt = no
string_mask = utf8only
distinguished_name = req_distinguished_name

[ req_distinguished_name ]
countryName = ES
stateOrProvinceName = MA
localityName = Tres Cantos
organizationName = eProsima
emailAddress = example@eprosima.com
commonName = DomainParticipantName

After writing the DomainParticipant certificate configuration file, next commands generate the X.509 certificate, using ECDSA, for a DomainParticipant.

openssl ecparam -name prime256v1 > ecdsaparam

openssl req -nodes -new \
  -newkey ec:ecdsaparam \
  -config partconf.cnf \
  -keyout partkey.pem \
  -out partreq.pem

openssl ca -batch -create_serial \
  -config maincaconf.cnf \
  -days 3650 \
  -in partreq.pem \
  -out partcert.pem
8.1.1.3. Generating the Certificate Revocation List (CRL)

Finally, the CRL is created. This is a list of the X.509 certificates revoked by the certificate issuing CA before they reach their expiration date. Any certificate that is on this list will no longer be trusted. To create a CRL using OpenSSL just run the following commands.

echo -ne '00' > crlnumber

openssl ca -gencrl \
  -config maincaconf.cnf \
  -cert maincacert.pem \
  -keyfile maincakey.pem \
  -out crl.pem

As an example, below is shown how to add the X.509 certificate of a DomainParticipant to the CRL.

openssl ca \
  -config maincaconf.cnf \
  -cert maincacert.pem \
  -keyfile maincakey.pem \
  -revoke partcert.pem

openssl ca -gencrl \
  -config maincaconf.cnf \
  -cert maincacert.pem \
  -keyfile maincakey.pem \
  -out crl.pem

8.2. Access control plugin: DDS:Access:Permissions

The access control plugin provides the mechanisms and operations required for validating the DomainParticipant permissions. If the security module was activated at Fast DDS compilation, after a remote DomainParticipant is authenticated, its permissions need to be validated and enforced.

Access rights that each DomainParticipant has over a resource are defined using the access control plugin. For the proper functioning of a DomainParticipant in a DDS Domain, the DomainParticipant must be authorized to operate in that specific domain. The DomainParticipant is responsible for creating the DataWriters and DataReaders that communicate over a certain Topic. Hence, a DomainParticipant must have the permissions needed to create a Topic, to publish through its DataWriters under defined Topics, and to subscribe via its DataReaders to other Topics. Access control plugin can configure the Cryptographic plugin as its usage is based on the DomainParticipant’s permissions.

The authentication plugin implemented in Fast DDS is referred to as “DDS:Access:Permissions”, in compliance with the DDS Security specification. This plugin is explained in detail below.

This builtin plugin provides access control using a permissions document signed by a trusted CA. The DDS:Access:Permissions plugin requires three documents for its configuration which contents are explained in detail below.

  1. The Permissions CA certificate.

  2. The Domain governance signed by the Permissions CA.

  3. The DomainParticipant permissions signed by the Permissions CA.

The DDS:Access:Permissions authentication plugin, can be activated setting the DomainParticipantQos properties() dds.sec.access.plugin with the value builtin.Access-Permissions. The following table outlines the properties used for the DDS:Access:Permissions plugin configuration.

Property name

Property value

permissions_ca

URI to the X509 certificate of the Permissions CA.
Supported URI schemes: file.
The file schema shall refer to an X.509 v3 certificate in PEM format.

governance

URI to shared Governance Document signed by the Permissions CA
in S/MIME format.
Supported URI schemes: file.

permissions

URI to the Participant permissions document signed by the
Permissions CA in S/MIME format.
Supported URI schemes: file.

transmit_algorithms_as_legacy (optional)

Whether to transmit algorithm identifiers in non-standard legacy format.
Will default to false if the property is not present.

Note

All listed properties have “dds.sec.access.builtin.Access-Permissions.” prefix. For example: dds.sec.access.builtin.Access-Permissions.permissions_ca.

The following is an example of how to set the properties of DomainParticipantQos for the DDS:Access:Permissions configuration.

DomainParticipantQos pqos;

// Activate DDS:Access:Permissions plugin
pqos.properties().properties().emplace_back("dds.sec.access.plugin",
        "builtin.Access-Permissions");

// Configure DDS:Access:Permissions plugin
pqos.properties().properties().emplace_back(
    "dds.sec.access.builtin.Access-Permissions.permissions_ca",
    "file://certs/maincacert.pem");
pqos.properties().properties().emplace_back(
    "dds.sec.access.builtin.Access-Permissions.governance",
    "file://certs/governance.smime");
pqos.properties().properties().emplace_back(
    "dds.sec.access.builtin.Access-Permissions.permissions",
    "file://certs/permissions.smime");
pqos.properties().properties().emplace_back(
    "dds.sec.access.builtin.Access-Permissions.transmit_algorithms_as_legacy",
    "true");
<participant profile_name="secure_domainparticipant_conf_access_control_plugin_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Activate DDS:Access:Permissions plugin -->
                <property>
                    <name>dds.sec.access.plugin</name>
                    <value>builtin.Access-Permissions</value>
                </property>
                <!-- Configure DDS:Access:Permissions plugin -->
                <property>
                    <name>dds.sec.access.builtin.Access-Permissions.permissions_ca</name>
                    <value>file://maincacet.pem</value>
                </property>
                <property>
                    <name>dds.sec.access.builtin.Access-Permissions.governance</name>
                    <value>file://governance.smime</value>
                </property>
                <property>
                    <name>dds.sec.access.builtin.Access-Permissions.permissions</name>
                    <value>file://permissions.smime</value>
                </property>
                <property>
                    <name>dds.sec.access.builtin.Access-Permissions.transmit_algorithms_as_legacy</name>
                    <value>true</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>

8.2.1. Permissions CA Certificate

This is an X.509 certificate that contains the Public Key of the CA that will be used to sign the Domain Governance Document and the DomainParticipant Permissions Document.

8.2.2. Domain Governance Document

Domain Governance document is an XML document that specifies the mechanisms to secure the DDS Domain. It shall be signed by the Permissions CA in S/MIME format. The XML scheme of this document is defined in Domain Governance XSD. The following is an example of the Domain Governance XML file contents.

 1<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 2    xsi:noNamespaceSchemaLocation="omg_shared_ca_domain_governance.xsd">
 3    <domain_access_rules>
 4        <domain_rule>
 5            <domains>
 6                <id_range>
 7                    <min>0</min>
 8                    <max>230</max>
 9                </id_range>
10            </domains>
11            <allow_unauthenticated_participants>false</allow_unauthenticated_participants>
12            <enable_join_access_control>true</enable_join_access_control>
13            <discovery_protection_kind>ENCRYPT</discovery_protection_kind>
14            <liveliness_protection_kind>ENCRYPT</liveliness_protection_kind>
15            <rtps_protection_kind>ENCRYPT</rtps_protection_kind>
16            <topic_access_rules>
17                <topic_rule>
18                    <topic_expression>HelloWorldTopic</topic_expression>
19                    <enable_discovery_protection>true</enable_discovery_protection>
20                    <enable_liveliness_protection>false</enable_liveliness_protection>
21                    <enable_read_access_control>true</enable_read_access_control>
22                    <enable_write_access_control>true</enable_write_access_control>
23                    <metadata_protection_kind>ENCRYPT</metadata_protection_kind>
24                    <data_protection_kind>ENCRYPT</data_protection_kind>
25                </topic_rule>
26            </topic_access_rules>
27        </domain_rule>
28    </domain_access_rules>
29</dds>

The Governance XSD file and the Governance XML example can also be downloaded from the eProsima Fast DDS Github repository.

8.2.2.1. Domain Rules

It allows the application of rules to the DDS Domain. The domain rules define aspects of the DDS Domain such as:

  • Whether the discovery data should be protected and the type of protection: MAC only or encryption followed by MAC.

  • Whether the whole RTPS message should be encrypted.

  • Whether the liveliness of the messages should be protected.

  • Whether a non-authenticated DomainParticipant can access or not to the unprotected discovery metatraffic and unprotected Topics.

  • Whether an authenticated DomainParticipant can access the domain without evaluating the access control policies.

  • Whether discovery information on a certain Topic should be sent with secure DataWriters.

  • Whether or not the access to Topics should be restricted to DomainParticipants with the appropriate permission to read them.

  • Whether the metadata sent on a certain Topic should be protected and the type of protection.

  • Whether payload data on a certain Topic should be protected and the type of protection.

The domain rules are evaluated in the same order as they appear in the document. A rule only applies to a particular DomainParticipant if the domain section matches the DDS Domain_Id to which the DomainParticipant belongs. If multiple rules match, the first rule that matches is the only one that applies. Each domain rule is delimited by the <domain_rule> XML element tag.

Some domain rules may have an additional configuration if enabled. This configuration defines the level of protection that the rule applies to the domain:

  • NONE: no cryptographic transformation is applied.

  • SIGN: cryptographic transformation based on Message Authentication Code (MAC) is applied, without additional encryption.

  • ENCRYPT: the data is encrypted and followed by a MAC computed on the ciphertext, also known as Encrypt-then-MAC.

The following table summarizes the elements and sections that each domain rule may contain.

Type

Name

XML element tag

Values

Element

Allow Unauthenticated Participants

<allow_unauthenticated_participants>

false

true

Enable Join Access Control

<enable_join_access_control>

false

true

Discovery Protection Kind

<discovery_protection_kind>

SIGN

ENCRYPT

NONE

Liveliness Protection Kind

<liveliness_protection_kind>

SIGN

ENCRYPT

NONE

RTPS Protection Kind

<rtps_protection_kind>

SIGN

ENCRYPT

NONE

Section

Domains

<domains>

<domains>

Topic Access Rules

<topic_access_rules>

<topic_rule>

The following describes the possible configurations of each of the elements and sections listed above that are contained in the domain rules.

8.2.2.1.1. Domains

This element is delimited by the <domains> XML element tag. The value in this element identifies the collection of DDS Domains to which the rule applies. The <domains> element can contain:

  • A single domain identifier:

<domains>
    <id>1</id>
</domains>
  • A range of domain identifiers:

<domains>
    <id_range>
        <min>1</min>
        <max>10</max>
    </id_range>
</domains>

Or a combination of both, a list of domain identifiers and ranges of domain identifiers.

8.2.2.1.2. Allow Unauthenticated Participants

This element is delimited by the <allow_unauthenticated_participants> XML element tag. It indicates whether the matching of a DomainParticipant with a remote DomainParticipant requires authentication. The possible values for this element are:

  • false: the DomainParticipant shall enforce the authentication of remote DomainParticipants and disallow matching those that cannot be successfully authenticated.

  • true: the DomainParticipant shall allow matching other DomainParticipants (event if the remote DomainParticipant cannot authenticate) as long as there is not an already valid authentication with the same DomainParticipant’s GUID.

In accordance with the DDS Security specification, the following premises should be considered:

  • Topics protected with enable_read_access_control or enable_write_access_control will not communicate regardless of the allow_unauthenticated_participants flag value.

  • If RTPS Protection Kind is not NONE and Allow Unauthenticated Participants is enabled, the entity creation will fail with an error.

  • Authentication is always attempted first regardless of <allow_unauthenticated_participants> configuration.

8.2.2.1.3. Enable Join Access Control

This element is delimited by the <enable_join_access_control> XML element tag. Indicates whether the matching of the participant with a remote DomqainParticipant requires authorization by the DDS:Access:Permissions plugin. Its possible values are:

  • false: the DomainParticipant shall not check the permissions of the authenticated remote DomainParticipant.

  • true: the DomainParticipant shall check the permissions of the authenticated remote DomainParticipant.

8.2.2.1.4. Discovery Protection Kind

This element is delimited by the <discovery_protection_kind> XML element tag. Indicates whether the secure channel of the endpoint discovery phase needs to be encrypted. The possible values are:

  • NONE: the secure channel shall not be protected.

  • SIGN: the secure channel shall be protected by MAC.

  • ENCRYPT: the secure channel shall be encrypted.

8.2.2.1.5. Liveliness Protection Kind

This element is delimited by the <liveliness_protection_kind> XML element tag. Indicates whether the secure channel of the liveliness mechanism needs to be encrypted. The possible values are:

  • NONE: the secure channel shall not be protected.

  • SIGN: the secure channel shall be protected by MAC.

  • ENCRYPT: the secure channel shall be encrypted.

8.2.2.1.6. RTPS Protection Kind

This element is delimited by the <rtps_protection_kind> XML element tag. Indicates whether the whole RTPS Message needs to be encrypted. The possible values are:

  • NONE: whole RTPS Messages shall not be protected.

  • SIGN: whole RTPS Messages shall be protected by MAC.

  • ENCRYPT: whole RTPS Messages shall be encrypted.

8.2.2.1.7. Topic Rule

This element is delimited by the <topic_rule> XML element tag and appears within the Topic Access Rules Section whose XML element tag is <topic_access_rules>. The following table summarizes the elements and sections that each domain rule may contain.

Elements

XML element tag

Values

Topic expression

<topic_expression>

Topic name

Enable Discovery Protection

<enable_discovery_protection>

false

true

Enable Liveliness Protection

<enable_liveliness_protection>

false

true

Enable Read Access Control

<enable_read_access_control>

false

true

Enable Write Access Control

<enable_write_access_control>

false

true

Metadata protection Kind

<metadata_protection_kind>

SIGN

ENCRYPT

NONE

Data protection Kind

<data_protection_kind>

SIGN

ENCRYPT

NONE

The topic expression within the rules selects a set of Topic names. The rule applies to any DataReader or DataWriter associated with a Topic whose name matches the Topic expression name. The topic access rules are evaluated in the same order as they appear within the <topic_access_rules> section. If multiple rules match, the first rule that matches is the only one that applies. If no matching <topic_rule> is found, the entity creation will fail.

Topic expression

This element is delimited by the <topic_expression> XML element tag. The value in this element identifies the set of Topic names to which the rule applies. The rule applies to any DataReader or DataWriter associated with a Topic whose name matches the value.

The Topic name expression syntax and matching shall use the syntax and rules of the POSIX fnmatch() function as specified in IEEE 1003.1-2017.

Enable Discovery Protection

This element is delimited by the <enable_discovery_protection> XML element tag. Indicates whether the entity related discovery information shall go through the secure channel of endpoint discovery phase.

  • false: the entity discovery information shall be sent by an unsecured channel of discovery.

  • true: the information shall be sent by the secure channel.

Enable Liveliness Protection

This element is delimited by the <enable_liveliness_protection> XML element tag. Indicates whether the entity related liveliness information shall go through the secure channel of liveliness mechanism.

  • false: the entity liveliness information shall be sent by an unsecured channel of liveliness.

  • true: the information shall be sent by the secure channel.

Enable Read Access Control

This element is delimited by the <enable_read_access_control> XML element tag. Indicates whether read access to the Topic is protected.

  • false: then local Subscriber creation and remote Subscriber matching can proceed without further access-control mechanisms imposed.

  • true: they shall be checked using Access control plugin.

Enable Write Access Control

This element is delimited by the <enable_write_access_control> XML element tag. Indicates whether write access to the Topic is protected.

  • false: then local Publisher creation and remote Publisher matching can proceed without further access-control mechanisms imposed.

  • true: they shall be checked using Access control plugin.

Metadata Protection Kind

This element is delimited by the <metadata_protection_kind> XML element tag. Indicates whether the entity’s RTPS submessages shall be encrypted by the Cryptographic plugin.

  • NONE: shall not be protected.

  • SIGN: shall be protected by MAC.

  • ENCRYPT: shall be encrypted.

Data Protection Kind

This element is delimited by the <data_protection_kind> XML element tag. Indicates whether the data payload shall be encrypted by the Cryptographic plugin.

  • NONE: shall not be protected.

  • SIGN: shall be protected by MAC.

  • ENCRYPT: shall be encrypted.

Domain Governance XSD
 1<?xml version="1.0" encoding="UTF-8"?>
 2<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 3    elementFormDefault="qualified" attributeFormDefault="unqualified">
 4    <xs:element name="dds" type="DomainAccessRulesNode" />
 5    <xs:complexType name="DomainAccessRulesNode">
 6        <xs:sequence minOccurs="1" maxOccurs="1">
 7            <xs:element name="domain_access_rules"
 8                type="DomainAccessRules" />
 9        </xs:sequence>
10    </xs:complexType>
11    <xs:complexType name="DomainAccessRules">
12        <xs:sequence minOccurs="1" maxOccurs="unbounded">
13            <xs:element name="domain_rule" type="DomainRule" />
14        </xs:sequence>
15    </xs:complexType>
16    <xs:complexType name="DomainRule">
17        <xs:sequence minOccurs="1" maxOccurs="1">
18            <xs:element name="domains" type="DomainIdSet" />
19            <xs:element name="allow_unauthenticated_participants"
20                type="xs:boolean" />
21            <xs:element name="enable_join_access_control"
22                type="xs:boolean" />
23            <xs:element name="discovery_protection_kind"
24                type="ProtectionKind" />
25            <xs:element name="liveliness_protection_kind"
26                type="ProtectionKind" />
27            <xs:element name="rtps_protection_kind"
28                type="ProtectionKind" />
29            <xs:element name="topic_access_rules"
30                type="TopicAccessRules" />
31        </xs:sequence>
32    </xs:complexType>
33    <xs:complexType name="DomainIdSet">
34        <xs:choice minOccurs="1" maxOccurs="unbounded">
35            <xs:element name="id" type="DomainId" />
36            <xs:element name="id_range" type="DomainIdRange" />
37        </xs:choice>
38    </xs:complexType>
39    <xs:simpleType name="DomainId">
40        <xs:restriction base="xs:nonNegativeInteger" />
41    </xs:simpleType>
42    <xs:complexType name="DomainIdRange">
43        <xs:choice>
44            <xs:sequence>
45                <xs:element name="min" type="DomainId" />
46                <xs:element name="max" type="DomainId" minOccurs="0" />
47            </xs:sequence>
48            <xs:element name="max" type="DomainId" />
49        </xs:choice>
50    </xs:complexType>
51    <xs:simpleType name="ProtectionKind">
52        <xs:restriction base="xs:string">
53            <xs:enumeration value="ENCRYPT_WITH_ORIGIN_AUTHENTICATION" />
54            <xs:enumeration value="SIGN_WITH_ORIGIN_AUTHENTICATION" />
55            <xs:enumeration value="ENCRYPT" />
56            <xs:enumeration value="SIGN" />
57            <xs:enumeration value="NONE" />
58        </xs:restriction>
59    </xs:simpleType>
60    <xs:simpleType name="BasicProtectionKind">
61        <xs:restriction base="ProtectionKind">
62            <xs:enumeration value="ENCRYPT" />
63            <xs:enumeration value="SIGN" />
64            <xs:enumeration value="NONE" />
65        </xs:restriction>
66    </xs:simpleType>
67    <xs:complexType name="TopicAccessRules">
68        <xs:sequence minOccurs="1" maxOccurs="unbounded">
69            <xs:element name="topic_rule" type="TopicRule" />
70        </xs:sequence>
71    </xs:complexType>
72    <xs:complexType name="TopicRule">
73        <xs:sequence minOccurs="1" maxOccurs="1">
74            <xs:element name="topic_expression" type="TopicExpression" />
75            <xs:element name="enable_discovery_protection"
76                type="xs:boolean" />
77            <xs:element name="enable_liveliness_protection"
78                type="xs:boolean" />
79            <xs:element name="enable_read_access_control"
80                type="xs:boolean" />
81            <xs:element name="enable_write_access_control"
82                type="xs:boolean" />
83            <xs:element name="metadata_protection_kind"
84                type="ProtectionKind" />
85            <xs:element name="data_protection_kind"
86                type="BasicProtectionKind" />
87        </xs:sequence>
88    </xs:complexType>
89    <xs:simpleType name="TopicExpression">
90        <xs:restriction base="xs:string" />
91    </xs:simpleType>
92</xs:schema>

Back to the Domain Governance Document.

8.2.3. DomainParticipant Permissions Document

The permissions document is an XML file which contains the permissions of a DomainParticipant and binds them to the DomainParticipant distinguished name defined in the DDS:Auth:PKI-DH plugin. The permissions document shall be signed by the Permissions CA in S/MIME format. The XML scheme of this document is defined in DomainParticipant Permissions XSD. The following is an example of the DomainParticipant Permissions XML file contents.

 1<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 2    xsi:noNamespaceSchemaLocation="http://www.omg.org/spec/DDS-Security/20170801/omg_shared_ca_permissions.xsd">
 3    <permissions>
 4        <grant name="ParticipantPermissions">
 5            <subject_name>emailAddress=example@eprosima.com, CN=DomainParticipantName, O=eProsima, ST=MA, C=ES</subject_name>
 6            <validity>
 7                <not_before>2013-06-01T13:00:00</not_before>
 8                <not_after>2038-06-01T13:00:00</not_after>
 9            </validity>
10            <allow_rule>
11                <domains>
12                    <id_range>
13                        <min>0</min>
14                        <max>230</max>
15                    </id_range>
16                </domains>
17                <publish>
18                    <topics>
19                        <topic>HelloWorldTopic</topic>
20                    </topics>
21                </publish>
22            </allow_rule>
23            <default>DENY</default>
24        </grant>
25
26        <!-- Fill the subject name with the information specified in the Participant certificate -->
27        <grant name="OtherParticipantPermissions">
28            <subject_name> emailAddress=xxx@eprosima.com, CN=xxx, OU=x, O=x, ST=XX, C=XX</subject_name>
29            <validity>
30                <not_before>2013-06-01T13:00:00</not_before>
31                <not_after>2038-06-01T13:00:00</not_after>
32            </validity>
33            <allow_rule>
34                <domains>
35                    <id_range>
36                        <min>0</min>
37                        <max>230</max>
38                    </id_range>
39                </domains>
40                <subscribe>
41                    <topics>
42                        <topic>HelloWorldTopic</topic>
43                    </topics>
44                </subscribe>
45            </allow_rule>
46            <default>DENY</default>
47        </grant>
48    </permissions>
49</dds>

The Permissions XSD file and the Permissions XML example can also be downloaded from the eProsima Fast DDS Github repository.

8.2.3.1. Grant Section

This section is delimited by the <grant> XML element tag. Each grant section contains three sections:

  • Subject name

  • Validity

  • Rules

8.2.3.1.1. Subject name

This section is delimited by XML element <subject_name>. The subject name identifies the DomainParticipant to which the permissions apply. Each subject name can only appear in a single <permissions> section within the XML Permissions document. The contents of the subject name element shall be the X.509 subject name of the DomainParticipant that was given in the authorization X.509 Certificate.

8.2.3.1.2. Validity

This section is delimited by the XML element <validity>. It reflects the valid dates for the permissions.

8.2.3.1.3. Rules

This section contains the permissions assigned to the DomainParticipant. The rules are applied in the same order that appears in the document. If the criteria for the rule matched the Domain join, publish or subscribe operation that is being attempted, then the allow or deny decision is applied. If the criteria for a rule does not match the operation being attempted, the evaluation shall proceed to the next rule. If all rules have been examined without a match, then the decision specified by the <default> rule is applied. The default rule, if present, must appear after all allow and deny rules. If the default rule is not present, the implied default decision is DENY.

For the grant to match there shall be a match of the topics and partitions criteria.

Allow rules are delimited by the XML element <allow_rule>. Deny rules are delimited by the XML element``<deny_rule>``. Both contain the same element children.

8.2.3.2. Domains Section

This section is delimited by the XML element <domains>. The value in this element identifies the collection of DDS Domains to which the rule applies. The syntax is the same as for the Domains of the Domain Governance Document.

8.2.3.3. Format of the Allowed/Denied Actions sections

The sections for each of the three actions have a similar format. The only difference is the name of the XML element used to delimit the action:

Action

XML element tag

Allow/Deny Publish

<publish>

Allow/Deny Subscribe

<subscribe>

Allow/Deny Relay

<relay>

Each action contains two conditions.

8.2.3.3.1. Topics Condition

This section is delimited by the <topics> XML element. It defines the Topic names that must be matched for the allow/deny rule to apply. Topic names may be given explicitly or by means of Topic name expressions. Each explicit topic name or Topic name expressions appears separately in a <topic> sub-element within the <topics> element.

The Topic name expression syntax and matching shall use the syntax and rules of the POSIX fnmatch() function as specified in

<topics>
    <topic>Plane</topic>
    <topic>Hel*</topic>
</topics>
8.2.3.3.2. Partitions Condition

This section is delimited by the <partitions> XML element. It limits the set Partitions names that may be associated with the (publish, subscribe, relay) action for the rule to apply. Partition names expression syntax and matching shall use the syntax and rules of the POSIX fnmatch() function as specified in IEEE 1003.1-2017. If there is no <partitions> section within a rule, then the default “empty string” partition is assumed.

<partitions>
    <partition>A</partition>
    <partition>B*</partition>
</partitions>
DomainParticipant Permissions XSD
  1<?xml version="1.0" encoding="utf-8"?>
  2<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  3    elementFormDefault="qualified" attributeFormDefault="unqualified">
  4    <xs:element name="dds" type="PermissionsNode" />
  5    <xs:complexType name="PermissionsNode">
  6        <xs:sequence minOccurs="1" maxOccurs="1">
  7            <xs:element name="permissions" type="Permissions" />
  8        </xs:sequence>
  9    </xs:complexType>
 10    <xs:complexType name="Permissions">
 11        <xs:sequence minOccurs="1" maxOccurs="unbounded">
 12            <xs:element name="grant" type="Grant" />
 13        </xs:sequence>
 14    </xs:complexType>
 15    <xs:complexType name="Grant">
 16        <xs:sequence minOccurs="1" maxOccurs="1">
 17            <xs:element name="subject_name" type="xs:string" />
 18            <xs:element name="validity" type="Validity" />
 19            <xs:sequence minOccurs="1" maxOccurs="unbounded">
 20                <xs:choice minOccurs="1" maxOccurs="1">
 21                    <xs:element name="allow_rule" minOccurs="0" type="Rule" />
 22                    <xs:element name="deny_rule" minOccurs="0" type="Rule" />
 23                </xs:choice>
 24            </xs:sequence>
 25            <xs:element name="default" type="DefaultAction" />
 26        </xs:sequence>
 27        <xs:attribute name="name" type="xs:string" use="required" />
 28    </xs:complexType>
 29    <xs:complexType name="Validity">
 30        <xs:sequence minOccurs="1" maxOccurs="1">
 31            <xs:element name="not_before" type="xs:dateTime" />
 32            <xs:element name="not_after" type="xs:dateTime" />
 33        </xs:sequence>
 34    </xs:complexType>
 35    <xs:complexType name="Rule">
 36        <xs:sequence minOccurs="1" maxOccurs="1">
 37            <xs:element name="domains" type="DomainIdSet" />
 38            <xs:sequence minOccurs="0" maxOccurs="unbounded">
 39                <xs:element name="publish" type="Criteria" />
 40            </xs:sequence>
 41            <xs:sequence minOccurs="0" maxOccurs="unbounded">
 42                <xs:element name="subscribe" type="Criteria" />
 43            </xs:sequence>
 44            <xs:sequence minOccurs="0" maxOccurs="unbounded">
 45                <xs:element name="relay" type="Criteria" />
 46            </xs:sequence>
 47        </xs:sequence>
 48    </xs:complexType>
 49    <xs:complexType name="DomainIdSet">
 50        <xs:choice minOccurs="1" maxOccurs="unbounded">
 51            <xs:element name="id" type="DomainId" />
 52            <xs:element name="id_range" type="DomainIdRange" />
 53        </xs:choice>
 54    </xs:complexType>
 55    <xs:simpleType name="DomainId">
 56        <xs:restriction base="xs:nonNegativeInteger" />
 57    </xs:simpleType>
 58    <xs:complexType name="DomainIdRange">
 59        <xs:choice>
 60            <xs:sequence>
 61                <xs:element name="min" type="DomainId" />
 62                <xs:element name="max" type="DomainId" minOccurs="0" />
 63            </xs:sequence>
 64            <xs:element name="max" type="DomainId" />
 65        </xs:choice>
 66    </xs:complexType>
 67    <xs:complexType name="Criteria">
 68        <xs:all minOccurs="1">
 69            <xs:element name="topics" minOccurs="1"
 70                type="TopicExpressionList" />
 71            <xs:element name="partitions" minOccurs="0"
 72                type="PartitionExpressionList" />
 73            <xs:element name="data_tags" minOccurs="0" type="DataTags" />
 74        </xs:all>
 75    </xs:complexType>
 76    <xs:complexType name="TopicExpressionList">
 77        <xs:sequence minOccurs="1" maxOccurs="unbounded">
 78            <xs:element name="topic" type="TopicExpression" />
 79        </xs:sequence>
 80    </xs:complexType>
 81    <xs:complexType name="PartitionExpressionList">
 82        <xs:sequence minOccurs="1" maxOccurs="unbounded">
 83            <xs:element name="partition" type="PartitionExpression" />
 84        </xs:sequence>
 85    </xs:complexType>
 86    <xs:simpleType name="TopicExpression">
 87        <xs:restriction base="xs:string" />
 88    </xs:simpleType>
 89    <xs:simpleType name="PartitionExpression">
 90        <xs:restriction base="xs:string" />
 91    </xs:simpleType>
 92    <xs:complexType name="DataTags">
 93        <xs:sequence minOccurs="1" maxOccurs="unbounded">
 94            <xs:element name="tag" type="TagNameValuePair" />
 95        </xs:sequence>
 96    </xs:complexType>
 97    <xs:complexType name="TagNameValuePair">
 98        <xs:sequence minOccurs="1" maxOccurs="unbounded">
 99            <xs:element name="name" type="xs:string" />
100            <xs:element name="value" type="xs:string" />
101        </xs:sequence>
102    </xs:complexType>
103    <xs:simpleType name="DefaultAction">
104        <xs:restriction base="xs:string">
105            <xs:enumeration value="ALLOW" />
106            <xs:enumeration value="DENY" />
107        </xs:restriction>
108    </xs:simpleType>
109</xs:schema>

Back to the DomainParticipant Permissions Document.

8.2.4. Signing documents using x509 certificate

Domain Governance Document and DomainParticipant Permissions Document have to be signed using an X.509 certificate. Generation of an X.509 certificate is explained in Generation of X.509 certificates. Next commands sign the necessary documents for its use by the DDS:Access:Permissions plugin.

# Governance document: governance.xml
openssl smime -sign -in governance.xml -text -out governance.smime -signer maincacert.pem -inkey maincakey.pem

# Permissions document: permissions.xml
openssl smime -sign -in permissions.xml -text -out permissions.smime -signer maincacert.pem -inkey maincakey.pem

8.3. Cryptographic plugin: DDS:Crypto:AES-GCM-GMAC

The cryptographic plugin provides the tools and operations required to support encryption and decryption, digests computation, message authentication codes computation and verification, key generation, and key exchange for DomainParticipants, DataWriters and DataReaders. Encryption can be applied over three different levels of DDS protocol:

  • The whole RTPS messages.

  • The RTPS submessages of a specific DDS Entity (DataWriter or DataReader).

  • The payload (user data) of a particular DataWriter.

The authentication plugin implemented in Fast DDS is referred to as “DDS:Crypto:AES-GCM-GMAC”, in compliance with the DDS Security specification. This plugin is explained in detail below.

The DDS:Crypto:AES-GCM-GMAC plugin provides authentication encryption using Advanced Encryption Standard (AES) in Galois Counter Mode (AES-GCM). It supports 128 bits and 256 bits AES key sizes. It may also provide additional DataReader-specific Message Authentication Codes (MACs) using Galois MAC (AES-GMAC).

The DDS:Crypto:AES-GCM-GMAC authentication plugin, can be activated setting the DomainParticipantQos properties() dds.sec.crypto.plugin with the value builtin.AES-GCM-GMAC. Moreover, this plugin needs the activation of the Authentication plugin: DDS:Auth:PKI-DH. The DDS:Crypto:AES-GCM-GMAC plugin is configured using the Access control plugin: DDS:Access:Permissions, i.e the cryptography plugin is configured through the properties and configuration files of the access control plugin.

The following is an example of how to set the properties of DomainParticipantQoS for the DDS:Crypto:AES-GCM-GMAC configuration.

DomainParticipantQos pqos;

// Activate DDS:Crypto:AES-GCM-GMAC plugin
pqos.properties().properties().emplace_back("dds.sec.crypto.plugin",
        "builtin.AES-GCM-GMAC");
<participant profile_name="secure_domainparticipant_conf_crypto_plugin_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Activate DDS:Crypto:AES-GCM-GMAC plugin -->
                <property>
                    <name>dds.sec.crypto.plugin</name>
                    <value>builtin.AES-GCM-GMAC</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>

8.4. Logging plugin: DDS:Logging:DDS_LogTopic

The logging plugin provides the necessary operations to log the security events triggered by the other security plugins supported by Fast DDS (Authentication plugin: DDS:Auth:PKI-DH, Access control plugin: DDS:Access:Permissions, and Cryptographic plugin: DDS:Crypto:AES-GCM-GMAC). Therefore, the aforementioned security plugins will use the logging plugin to log their events. These events can be reporting of expected behavior, as well as security breaches and errors.

The logging plugin implemented in Fast DDS collects all security event data of a DomainParticipant and saves them in a local file. The log messages generated by the logging plugin include an ID that uniquely identifies the DomainParticipant that triggered the event, the DDS Domain identifier to which the DomainParticipant belongs, and a time-stamp.

The logging plugin implemented in Fast DDS is referred to as “DDS:Logging:DDS_LogTopic”, in compliance with the DDS Security specification. This plugin is explained in detail below. This plugin can be configured to filter according to up to eight levels of severity of the messages.

The DDS:Logging:DDS_LogTopic authentication plugin, can be activated setting the DomainParticipantQos properties() dds.sec.log.plugin with the value builtin.DDS_LogTopic. The following table outlines the properties used for the DDS:Logging:DDS_LogTopic plugin configuration.

Property name

Property value

Value

Definition

logging_level

EMERGENCY_LEVEL

System is unusable. Should not continue use.

ALERT_LEVEL

Should be corrected immediately.

CRITICAL_LEVEL

A failure in primary application.

ERROR_LEVEL

General error conditions. Default value.

WARNING_LEVEL

May indicate future error if action not taken.

NOTICE_LEVEL

Unusual, but nor erroneous event or condition.

INFORMATIONAL_LEVEL

Normal operational. Requires no action.

DEBUG_LEVEL

Normal operational.

log_file

Path of the file in which the log messages are to be saved.

Note

All listed properties have “dds.sec.log.builtin.DDS_LogTopic.” prefix. For example: dds.sec.log.builtin.DDS_LogTopic.logging_level.

The following is an example of how to set the properties of DomainParticipantQoS for the DDS:Logging:DDS_LogTopic plugin configuration.

DomainParticipantQos pqos;

// Activate DDS:Logging:DDS_LogTopic plugin
pqos.properties().properties().emplace_back("dds.sec.log.plugin",
        "builtin.DDS_LogTopic");

// Configure DDS:Logging:DDS_LogTopic plugin
pqos.properties().properties().emplace_back(
    "dds.sec.log.builtin.DDS_LogTopic.logging_level",
    "EMERGENCY_LEVEL");
pqos.properties().properties().emplace_back(
    "dds.sec.log.builtin.DDS_LogTopic.log_file",
    "myLogFile.log");
<participant profile_name="secure_domainparticipant_conf_logging_plugin_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Activate DDS:Auth:PKI-DH plugin -->
                <property>
                    <name>dds.sec.log.plugin</name>
                    <value>builtin.DDS_LogTopic</value>
                </property>
                <!-- Configure DDS:Auth:PKI-DH plugin -->
                <property>
                    <name>dds.sec.log.builtin.DDS_LogTopic.logging_level</name>
                    <value>EMERGENCY_LEVEL</value>
                </property>
                <property>
                    <name>dds.sec.log.builtin.DDS_LogTopic.log_file</name>
                    <value>myLogFile.log</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>

8.5. PKCS#11 support

The private key property used for the DDS:Auth:PKI-DH plugin configuration can be specified using a PKCS#11 compliant URI that represents a key stored in a HSM (Hardware Security Module). When a PKCS#11 URI is given, the private key is never taken out of the HSM, providing a more secure setup.

Support for PKCS#11 URIs is provided by the libp11 library. This library provides a PKCS#11 engine for OpenSSL that acts as a proxy between OpenSSL and the HSM driver provided by the manufacturer. To make OpenSSL aware of the new engine, the OpenSSL configuration file might need to be updated. For details on how to set up the PKCS#11 engine in different platforms follow the dedicated documentation:

Also, the following section contains the list of PropertyPolicyQos that can be set within Fast DDS Security: Security Property QoS Settings.

9. Logging

eProsima Fast DDS provides an extensible built-in logging module that exposes the following main functionalities:

This section is devoted to explain the use, configuration, and extensibility of Fast DDS’ logging module.

9.1. Module Structure

The logging module provides the following classes:

  • Log is the core class of the logging module. This singleton is not only in charge of the logging operations (see Logging Messages), but it also provides configuration APIs to set different logging configuration aspects (see Module Configuration), as well as logging filtering at various levels (see Filters). It contains zero or more LogConsumer objects. The singleton’s consuming thread feeds the log entries added to the logging queue using the macros defined in Logging Messages to the log consumers sequentially (see Logging Thread).

    Warning

    Log API exposes member function Log::QueueLog(). However, this function is not intended to be used directly. To add messages to the log queue, use the methods described in Logging Messages.

  • LogConsumer is the base class for all the log consumers (see Consumers). It includes the member functions that derived classes should overload to consume log entries.

_images/class_diagram.svg

Logging module class diagram

The module can be further extended by creating new consumer classes deriving from LogConsumer and/or OStreamConsumer. To enable a custom consumer just follow the instructions on Register Consumers.

9.2. Log Entry Specification

Log entries created by StdoutConsumer, StdoutErrConsumer and FileConsumer (eProsima Fast DDS built-in Consumers) adhere to the following structure:

<Timestamp> [<Category> <Verbosity Level>] <Message> (<File Name>:<Line Number>) -> Function <Function Name>

An example of such log entry is given by:

2020-05-27 11:45:47.447 [DOCUMENTATION_CATEGORY Error] This is an error message (example.cpp:50) -> Function main

Note

File Name and Line Number, as well as Function Name are only present when enabled. See Module Configuration for details.

9.3. Logging Thread

Calls to the macros presented in Logging Messages merely add the log entry to a ready-to-consume queue. Upon creation, the logging module spawns a thread that awakes every time an entry is added to the queue. When awaken, this thread feeds all the entries in the queue to all the registered Consumers. Once the work is done, the thread falls back into idle state. This strategy prevents the module from blocking the application thread when a logging operation is performed. However, sometimes applications may want to wait until the logging routine is done to continue their operation. The logging module provides this capability via the member function Log::Flush(). Furthermore, it is possible to completely eliminate the thread and its resources using member function Log::KillThread(). In addition, it is possible to configure certain settings of this logging thread via the member function Log::SetThreadConfig().

// Block current thread until the log queue is empty.
Log::Flush();

// Stop the loggin thread and free its resources.
Log::KillThread();

// Configure ThreadSettings for the logging thread
Log::SetThreadConfig(eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1});

Warning

A call to any of the macros present in Logging Messages will spawn the logging thread even if it has been previously killed with Log::KillThread().

9.4. Logging Messages

The logging of messages is handled by three dedicated macros, one for each available verbosity level (see Verbosity Level):

Said macros take exactly two arguments, a category and a message, and produce a log entry showing the message itself plus some meta information depending on the module’s configuration (see Log Entry Specification and Log Entry).

EPROSIMA_LOG_INFO(DOCUMENTATION_CATEGORY, "This is an info message");
EPROSIMA_LOG_WARNING(DOCUMENTATION_CATEGORY, "This is an warning message");
EPROSIMA_LOG_ERROR(DOCUMENTATION_CATEGORY, "This is an error message");

There exist some old log macros used in previous versions: logInfo, logWarning and logError. These macros are still available as long as user does not manually disable them by ENABLE_OLD_LOG_MACROS CMake option or in-site macro ENABLE_OLD_LOG_MACROS_ before including Log module. See section Old Log macros disable for more information.

Warning

Note that each message level is deactivated when CMake options LOG_NO_INFO, LOG_NO_WARNING or LOG_NO_ERROR are set to ON respectively. For more information about how to enable and disable each individual logging macro, please refer to Disable Logging Module.

9.5. Module Configuration

The logging module offers a variety of configuration options. The different components of a log entry (see Log Entry Specification) can be configured as explained in Log Entry. Furthermore, the logging module allows for registering several log consumer, allowing applications to direct the logging output to different destinations (see Register Consumers). In addition, some of the logging features can be configured using eProsima Fast DDS XML configuration files (see XML Configuration).

9.5.1. Log Entry

All the different components of a log entry are summarized in the following table (please refer to each component’s section for further explanation):

Component

Optional

Default

Timestamp

NO

ENABLED

Category

NO

ENABLED

Verbosity Level

NO

ENABLED

Message

NO

ENABLED

File Context

YES

DISABLED

Function Name

YES

ENABLED

9.5.1.1. Timestamp

The log timestamp follows the ISO 8601 standard for local timestamps, i.e. YYYY-MM-DD hh:mm:ss.sss. This component cannot be further configured or disabled.

9.5.1.2. Category

Log entries have a category assigned when producing the log via the macros presented in Logging Messages. The category component can be used to filter log entries so that only those categories specified in the filter are consumed (see Filters). This component cannot be further configured or disabled.

9.5.1.3. Verbosity Level

eProsima Fast DDS logging module provides three verbosity levels defined by the Log::Kind enumeration, those are:

The logging module’s verbosity level defaults to Log::Kind::Error, which means that only messages logged with EPROSIMA_LOG_ERROR would be consumed. The verbosity level can be set and retrieved using member functions Log::SetVerbosity() and Log::GetVerbosity() respectively.

// Set log verbosity level to Log::Kind::Info
Log::SetVerbosity(Log::Kind::Info);

// Get log verbosity level
Log::Kind verbosity_level = Log::GetVerbosity();

Warning

Setting any of the CMake options LOG_NO_INFO, LOG_NO_WARNING or LOG_NO_ERROR to ON will completely disable the corresponding verbosity level. LOG_NO_INFO is set to ON for Single-Config generators as default value if not in Debug mode.

9.5.1.4. Message

This component constitutes the body of the log entry. It is specified when producing the log via the macros presented in Logging Messages. The message component can be used to filter log entries so that only those entries whose message pattern-matches the filter are consumed (see Filters). This component cannot be further configured or disabled.

9.5.1.5. File Context

This component specifies the origin of the log entry in terms of file name and line number (see Logging Messages for a log entry example featuring this component). This is useful when tracing code flow for debugging purposes. The file context component can be enabled/disabled using the member function Log::ReportFilenames().

// Enable file name and line number reporting
Log::ReportFilenames(true);

// Disable file name and line number reporting
Log::ReportFilenames(false);
9.5.1.6. Function Name

This component specifies the origin of the log entry in terms of the function name (see Logging Messages for a log entry example featuring this component). This is useful when tracing code flow for debugging purposes. The function name component can be enabled/disabled using the member function Log::ReportFunctions().

// Enable function name reporting
Log::ReportFunctions(true);

// Disable function name reporting
Log::ReportFunctions(false);

9.5.2. Register Consumers

eProsima Fast DDS logging module supports zero or more consumers logging the entries registered in the logging queue with the methods described in Logging Messages. To register a consumer, the Log class exposes member function Log::RegisterConsumer()

// Create a FileConsumer consumer that logs entries in "archive.log"
std::unique_ptr<FileConsumer> file_consumer(new FileConsumer("archive.log"));
// Register the consumer. Log entries will be logged to STDOUT and "archive.log"
Log::RegisterConsumer(std::move(file_consumer));

The consumers list can be emptied with member function Log::ClearConsumers().

// Clear all the consumers. Log entries are discarded upon consumption.
Log::ClearConsumers();

Note

Registering and configuring consumers can also be done using Fast DDS XML configuration files. Please refer to XML Configuration for details.

Warning

Log::ClearConsumers() empties the consumers lists. All log entries are discarded until a new consumer is register via Log::RegisterConsumer(), or until Log::Reset() is called.

9.5.3. Reset Configuration

The logging module’s configuration can be reset to default settings with member function Log::Reset().

Warning

Resetting the module’s configuration entails:

9.5.4. XML Configuration

eProsima Fast DDS allows for registering and configuring log consumers using XML configuration files. Please refer to Log profiles for details.

9.6. Filters

eProsima Fast DDS logging module allows for log entry filtering when consuming the logs, so that an application execution output can be limited to specific areas of interest. Beside the Verbosity Level, Fast DDS provides three different filtering possibilities.

It is worth mentioning that filters are applied in the specific order presented above, meaning that file name filtering is only applied to the entries that pattern-match the category filter, and content filtering is only applied to the entries that pattern-match both category and file name filters.

9.6.1. Category Filtering

Log entries can be filtered upon consumption according to their Category component using regular expressions. Each time an entry is ready to be consumed, the category filter is applied using std::regex_search(). To set a category filter, member function Log::SetCategoryFilter() is used:

// Set filter using regular expression
Log::SetCategoryFilter(std::regex("(CATEGORY_1)|(CATEGORY_2)"));

// Would be consumed
EPROSIMA_LOG_ERROR(CATEGORY_1, "First log entry");
// Would be consumed
EPROSIMA_LOG_ERROR(CATEGORY_2, "Second log entry");
// Would NOT be consumed
EPROSIMA_LOG_ERROR(CATEGORY_3, "Third log entry");

The previous example would produce the following output:

2020-05-27 15:07:05.771 [CATEGORY_FILTER_1 Error] First log entry -> Function main
2020-05-27 15:07:05.771 [CATEGORY_FILTER_2 Error] Second log entry -> Function main

9.6.2. File Name Filtering

Log entries can be filtered upon consumption according to their File Context component using regular expressions. Each time an entry is ready to be consumed, the file name filter is applied using std::regex_search(). To set a file name filter, member function Log::SetFilenameFilter() is used:

// Filename: example.cpp

// Enable file name and line number reporting
Log::ReportFilenames(true);

// Set filter using regular expression so filename must match "example"
Log::SetFilenameFilter(std::regex("example"));
// Would be consumed
EPROSIMA_LOG_ERROR(CATEGORY, "First log entry");

// Set filter using regular expression so filename must match "other"
Log::SetFilenameFilter(std::regex("other"));
// Would NOT be consumed
EPROSIMA_LOG_ERROR(CATEGORY, "Second log entry");

The previous example would produce the following output:

2020-05-27 15:07:05.771 [CATEGORY Error] First log entry (example.cpp:50) -> Function main

Note

File name filters are applied even when the File Context entry component is disabled.

9.6.3. Content Filtering

Log entries can be filtered upon consumption according to their Message component using regular expressions. Each time an entry is ready to be consumed, the content filter is applied using std::regex_search(). To set a content filter, member function Log::SetErrorStringFilter() is used:

// Set filter using regular expression so message component must match "First"
Log::SetErrorStringFilter(std::regex("First"));
// Would be consumed
EPROSIMA_LOG_ERROR(CATEGORY, "First log entry");
// Would NOT be consumed
EPROSIMA_LOG_ERROR(CATEGORY, "Second log entry");

The previous example would produce the following output:

2020-05-27 15:07:05.771 [CATEGORY Error] First log entry -> Function main

9.6.4. Reset Logging Filters

The logging module’s filters can be reset with member function Log::Reset().

Warning

Resetting the module’s filters entails:

9.7. Consumers

Consumers are classes that take a Log::Entry and produce a log output accordingly. eProsima Fast DDS provides three different log consumers that output log entries to different streams:

9.7.1. StdoutConsumer

StdoutConsumer outputs log entries to STDOUT stream following the convection specified in Log Entry Specification. It is the default logging module if the CMake option LOG_CONSUMER_DEFAULT is set to STDOUT. It can be registered and unregistered using the methods explained in Register Consumers and Reset Configuration.

// Create a StdoutConsumer consumer that logs entries to stdout stream.
std::unique_ptr<StdoutConsumer> stdout_consumer(new StdoutConsumer());

// Register the consumer.
Log::RegisterConsumer(std::move(stdout_consumer));

9.7.2. StdoutErrConsumer

StdoutErrConsumer uses a Log::Kind threshold to filter the output of the log entries. Those log entries whose Log::Kind is equal to or more severe than the given threshold output to STDERR. Other log entries output to STDOUT. It is the default and only log consumer of the logging module if the CMake option LOG_CONSUMER_DEFAULT is set to AUTO, STDOUTERR, or not set at all. By default, the threshold is set to Log::Kind::Warning. StdoutErrConsumer::stderr_threshold() allows the user to modify the default threshold.

Additionally, if CMake option LOG_CONSUMER_DEFAULT is set to STDOUTERR, the logging module will use this consumer as the default log consumer.

// Create a StdoutErrConsumer consumer that logs entries to stderr only when the Log::Kind is equal to ERROR
std::unique_ptr<StdoutErrConsumer> stdouterr_consumer(new StdoutErrConsumer());
stdouterr_consumer->stderr_threshold(Log::Kind::Error);

// Register the consumer
Log::RegisterConsumer(std::move(stdouterr_consumer));

9.7.3. FileConsumer

FileConsumer provides the logging module with log-to-file logging capabilities. Applications willing to hold a persistent execution log record can specify a logging file using this consumer. Furthermore, the application can choose whether the file stream should be in “write” or “append” mode, according to the behaviour defined by std::fstream::open().

// Create a FileConsumer consumer that logs entries in "archive_1.log", opening the file in "write" mode.
std::unique_ptr<FileConsumer> write_file_consumer(new FileConsumer("archive_1.log", false));

// Create a FileConsumer consumer that logs entries in "archive_2.log", opening the file in "append" mode.
std::unique_ptr<FileConsumer> append_file_consumer(new FileConsumer("archive_2.log", true));

// Register the consumers.
Log::RegisterConsumer(std::move(write_file_consumer));
Log::RegisterConsumer(std::move(append_file_consumer));

9.8. Disable Logging Module

Setting the Verbosity Level, translates into entries not being added to the log queue if the entry’s level has lower importance than the set one. This check is performed when calling the macros defined in Logging Messages. However, it is possible to fully disable each macro (and therefore each verbosity level individually) at build time.

  • EPROSIMA_LOG_INFO is fully disabled by either:

    • Setting CMake option LOG_NO_INFO to ON (default for Single-Config generators if CMAKE_BUILD_TYPE is other than Debug).

    • Defining macro HAVE_LOG_NO_INFO to 1.

  • EPROSIMA_LOG_WARNING is fully disabled by either:

    • Setting CMake option LOG_NO_WARNING to ON.

    • Defining macro HAVE_LOG_NO_WARNING to 1.

  • EPROSIMA_LOG_ERROR is fully disabled by either:

    • Setting CMake option LOG_NO_ERROR to ON.

    • Defining macro HAVE_LOG_NO_ERROR to 1.

Applying either of the previously described methods will set the macro to be empty at configuration time, thus allowing the compiler to optimize the call out. This is done so that all the debugging messages present on the library are optimized out at build time if not building for debugging purposes, thus preventing them to impact performance.

INTERNAL_DEBUG CMake option activates log macros compilation, so the arguments of the macros are compiled. However:

  • It does not activate the log Warning and Error messages, i.e. the messages are not written in the log queue.

  • EPROSIMA_LOG_INFO has a special behaviour to simplify working with Multi-Config capability IDEs. If CMake option LOG_NO_INFO is OFF, or the C++ definition HAVE_LOG_NO_INFO is 0, then logging is enabled only for Debug configuration. In this scenario, setting FASTDDS_ENFORCE_LOG_INFO to ON will enable EPROSIMA_LOG_INFO even on non Debug configurations. This is specially useful when using the Fast DDS’ logging module in an external application which links with Fast DDS compiled in Release. In that case, applications wanting to use all three levels of logging can simply add the following code prior to including any Fast DDS header:

    #define HAVE_LOG_NO_INFO 0
    #define FASTDDS_ENFORCE_LOG_INFO 1
    

Warning

INTERNAL_DEBUG can be automatically set to ON if CMake option EPROSIMA_BUILD is set to ON.

9.9. Old Log macros disable

Before version 2.8.2, Fast DDS project used log macros: logInfo, logWarning and logError, which may collide with other libraries. These log macros have been replaced by new ones with a more specific format: (e.g. EPROSIMA_LOG_INFO). In order to disable old macros compilation, use CMake option ENABLE_OLD_LOG_MACROS = ON or define ENABLE_OLD_LOG_MACROS_ 0 before including the log module #include <fastdds/dds/log/Log.hpp>.

Warning

These macros will be deprecated in future versions of Fast DDS. The use of the new format ones is encouraged.

10. XML profiles

eProsima Fast DDS allows for loading XML configuration files, each one containing one or more XML profiles. In addition to the API functions for loading user XML files, Fast DDS tries to locate and load several XML files upon initialization. Fast DDS offers the following options:

  • Load an XML file named DEFAULT_FASTDDS_PROFILES.xml located in the current execution path.

  • Load an XML file which location is defined using the environment variable FASTDDS_DEFAULT_PROFILES_FILE (see FASTDDS_DEFAULT_PROFILES_FILE).

  • Load the configuration parameters directly from the classes’ definitions without looking for the DEFAULT_FASTDDS_PROFILES.xml in the working directory (see SKIP_DEFAULT_XML).

  • Load directly the XML as a string data buffer.

An XML profile is defined by a unique name that is used to reference the XML profile during the creation of an Entity, the Transport configuration, or the DynamicTypes definition.

Both options can be complemented, i.e. it is possible to load multiple XML files but these must not have XML profiles with the same name. This section explains how to configure DDS entities using XML profiles. This includes the description of all the configuration values available for each of the XML profiles, as well as how to create complete XML files.

10.1. Creating an XML profiles file

An XML file can contain several XML profiles. These XML profiles are defined within the <dds> element, and in turn, within the <profiles> XML elements. The possible topologies for the definition of XML profiles are specified in Rooted vs Standalone profiles definition.

It is worth mentioning that the first element of the xml profile must have the xmlns attribute with the link xmlns="http://www.eprosima.com", in both rooted or standalone definitions. That link defines the reference of the xsd schema that the xml document complies with.

The available profile types are:

The following sections will show implementation examples for each of these profiles.

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <domainparticipant_factory profile_name="domainparticipant_factory_profile">
            <!-- ... -->
        </domainparticipant_factory>

        <participant profile_name="participant_profile">
            <!-- ... -->
        </participant>

        <data_writer profile_name="datawriter_profile">
            <!-- ... -->
        </data_writer>

        <data_reader profile_name="datareader_profile">
            <!-- ... -->
        </data_reader>

        <topic profile_name="topic_profile">
            <!-- ... -->
        </topic>

        <transport_descriptors>
            <!-- ... -->
        </transport_descriptors>
    </profiles>

    <library_settings>
        <!-- ... -->
    </library_settings>

    <log>
        <!-- ... -->
    </log>

    <types>
        <!-- ... -->
    </types>
</dds>

Note

The Example section shows an XML file with all the possible configurations and profile types. This example is useful as a quick reference to look for a particular property and how to use it. The Fast DDS XSD scheme can be used as a quick reference too.

10.1.1. Loading and applying profiles

In case the user defines the Entity profiles via XML files, it is required to load these XML files using the load_XML_profiles_file() public member function before creating any entity. It is also possible to load directly the XML information as a string data buffer using the load_XML_profiles_string() public member function. Moreover, create_participant_with_profile(), create_publisher_with_profile(), create_subscriber_with_profile(), create_datawriter_with_profile(), and create_datareader_with_profile() member functions expect a profile name as an argument. Fast DDS searches the given profile name over all the loaded XML profiles, applying the profile to the entity if founded.

if (RETCODE_OK ==
        DomainParticipantFactory::get_instance()->load_XML_profiles_file("my_profiles.xml"))
{
    DomainParticipant* participant =
            DomainParticipantFactory::get_instance()->create_participant_with_profile(
        0, "participant_xml_profile");

    Topic* topic =
            participant->create_topic("TopicName", "DataTypeName", TOPIC_QOS_DEFAULT);

    Publisher* publisher = participant->create_publisher_with_profile("publisher_xml_profile");
    DataWriter* datawriter = publisher->create_datawriter_with_profile(topic, "datawriter_xml_profile");
    Subscriber* subscriber = participant->create_subscriber_with_profile("subscriber_xml_profile");
    DataReader* datareader = subscriber->create_datareader_with_profile(topic, "datareader_xml_profile");
}

// Load XML as string data buffer
std::string xml_profile =
        "\
        <?xml version=\"1.0\" encoding=\"UTF-8\" ?>\
        <dds>\
            <profiles xmlns=\"http://www.eprosima.com\" >\
                <data_writer profile_name=\"test_datawriter_profile\" is_default_profile=\"true\">\
                    <qos>\
                        <durability>\
                            <kind>TRANSIENT_LOCAL</kind>\
                        </durability>\
                    </qos>\
                </data_writer>\
            </profiles>\
        </dds>\
        ";
if (RETCODE_OK ==
        DomainParticipantFactory::get_instance()->load_XML_profiles_string(xml_profile.c_str(),
        xml_profile.length()))
{
    // Create DDS entities with profiles
}

For simplicity, the create_participant_with_default_profile() method takes the default profile set in the environment to create a participant. It requires the XML profile to have been already loaded. Please, refer to XML profiles for further information regarding loading profiles.

Warning

It is worth mentioning that if the same XML profile file is loaded multiple times, the second loading of the file will result in an error together with the consequent error log.

Note

To load dynamic types from XML files see the Loading XML Types profile in Fast DDS application subsection of Dynamic Types profiles.

10.1.2. Get QoS from raw XML profiles

Although the standard procedure is to first load XML profiles, and then create entities given the profile name of choice, it is also possible to get the desired QoS from the XML profile directly so it can be modified before being used. For this purpose, the following public methods are available:

For each qos kind there exists two method versions; with and without profile_name argument. When provided, the method searches for the given profile name in the loaded XML profiles, and results in error if not found. When not provided, the method fills the provided qos object with the first retrieved profile of the pertinent kind, and results in error when none found. In addition, there exists another method version which looks for the default profile of the pertinent kind in the provided XML string.

Following is an example of how to get the QoS from a raw XML profile and modify it before creating a new entity.

DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);

Topic* topic =
        participant->create_topic("TopicName", "DataTypeName", TOPIC_QOS_DEFAULT);

Publisher* publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);

// Load XML as string data buffer
std::string xml_profile =
        "\
        <?xml version=\"1.0\" encoding=\"UTF-8\" ?>\
        <dds>\
            <profiles xmlns=\"http://www.eprosima.com\" >\
                <data_writer profile_name=\"test_datawriter_profile\" is_default_profile=\"true\">\
                    <qos>\
                        <durability>\
                            <kind>TRANSIENT_LOCAL</kind>\
                        </durability>\
                    </qos>\
                </data_writer>\
            </profiles>\
        </dds>\
        ";

// Extract Qos from XML
DataWriterQos qos;
if (RETCODE_OK == publisher->get_datawriter_qos_from_xml(xml_profile, qos, "test_datawriter_profile"))
{
    // Modify extracted qos and use it to create DDS entities
}

10.1.3. Rooted vs Standalone profiles definition

Fast DDS offers various options for the definition of XML profiles. These options are:

  • Stand-alone: The element defining the XML profile is the root element of the XML file. Elements <dds>, <profiles>, <library_settings>, <types>, and <log> can be defined in a stand-alone manner.

  • Rooted: The element defining the XML profile is the child element of another element. For example, the <participant>, <data_reader>, <data_writer>, <topic>, and <transport_descriptors> elements must be defined as child elements of the <profiles> element.

The following is an example of the definition of the <types> XML profile using the two previously discussed approaches.

Stand-alone

<?xml version="1.0" encoding="UTF-8" ?>
<types xmlns="http://www.eprosima.com">
    <type>
        <!-- Type definition -->
    </type>

    <type>
        <!-- Type definition -->
        <!-- Type definition -->
    </type>
</types>

Rooted

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <types>
        <type>
            <!-- Type definition -->
        </type>

        <type>
            <!-- Type definition -->
            <!-- Type definition -->
        </type>
    </types>
</dds>

Note

Make sure that the first element of the xml profile must have the xmlns tag with the link xmlns="http://www.eprosima.com", in both rooted or standalone definitions.

10.1.4. Modifying predefined XML profiles

Some scenarios may require to modify some of the QoS after loading the XML profiles. For such cases the Types of Entities which act as factories provide methods to get the QoS from the XML profile. This allows the user to read and modify predefined XML profiles before applying them to a new entity.

if (RETCODE_OK ==
        DomainParticipantFactory::get_instance()->load_XML_profiles_file("my_profiles.xml"))
{
    DomainParticipantQos participant_qos;
    DomainParticipantFactory::get_instance()->get_participant_qos_from_profile(
        "participant_xml_profile",
        participant_qos);

    // Name obtained in another section of the code
    participant_qos.name() = custom_name;

    // Modify number of preallocations (this overrides the one set in the XML profile)
    participant_qos.allocation().send_buffers.preallocated_number = 10;

    // Create participant using the modified XML Qos
    DomainParticipant* participant =
            DomainParticipantFactory::get_instance()->create_participant(
        0, participant_qos);
}

10.1.5. Dynamic content by leveraging environment variables

For deployment scenarios that require part of the XML content to be dynamically generated, Fast DDS supports using environment variables on the text content of any XML tag. The format for environment variables expansion is ${ENV_VAR_NAME}, where ENV_VAR_NAME follows the restrictions from IEEE 1003.1:

Note

Environment variable names … consist solely of uppercase letters, digits, and the ‘_’ (underscore) from the characters defined in Portable Character Set and do not begin with a digit.

More than one environment variable can be used, and they can be mixed with literal text.

The expansion will take place when the XML file is loaded, so changing the value of an environment variable afterwards will have no effect.

The following is an example of an XML allowing a participant to exclusively communicate with the participants on a fixed IP address, taken from REMOTE_IP_ADDRESS environment variable. It also gives the participant a name that mixes literal text with the content from two environment variables.

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="env_var_parsing_example">
            <rtps>
                <name>This is app '${MY_APP_NAME}' running on host '${MY_HOST_NAME}'</name>
                <builtin>
                    <initialPeersList>
                        <locator>
                            <udpv4>
                                <address>${REMOTE_IP_ADDRESS}</address>
                            </udpv4>
                        </locator>
                    </initialPeersList>
                </builtin>
            </rtps>
        </participant>
    </profiles>
</dds>

Warning

The Fast DDS XSD schema does not support the environment variables expansion feature, so validation of an XML file with environment variables expansion expressions will fail.

10.2. DomainParticipantFactory profiles

The DomainParticipantFactory profiles allow the definition of the configuration of DomainParticipantFactory through XML files. These profiles are defined within the <domainparticipant_factory> XML tags.

10.2.1. DomainParticipantFactory XML attributes

The <domainparticipant_factory> element has two attributes defined: profile_name and is_default_profile.

Name

Description

Use

profile_name

Sets the name under which the <domainparticipant_factory> profile is registered in the
DDS Domain, so that it can be loaded later by the DomainParticipantFactory, as shown in
Loading and applying profiles.

Mandatory

is_default_profile

Sets the <domainparticipant_factory> profile as the default profile. Thus, if a default
profile exists, it will be used when creating the DomainParticipantFactory

Optional

10.2.2. DomainParticipantFactory configuration

The <domainparticipant_factory> element has the following children elements:

Name

Description

Values

<qos>

DomainParticipantFactory QoS.

QoS element type

10.2.2.1. QoS element type

Name

Description

Values

<entity_factory>

Entity factory QoS Policy.

Entity Factory

<shm_watchdog_thread>

ThreadSettings for the SHM watchdog thread.
See Concurrency and multithreading.

ThreadSettings

<file_watch_threads>

ThreadSettings for the File watch threads. See Concurrency and multithreading.

ThreadSettings

Example

<?xml version="1.0" encoding="UTF-8" ?>
<dds>
    <profiles xmlns="http://www.eprosima.com">
        <domainparticipant_factory profile_name="domainparticipant_factory_profile_name">
            <qos>
                <entity_factory>
                    <autoenable_created_entities>true</autoenable_created_entities>
                </entity_factory>
                <shm_watchdog_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </shm_watchdog_thread>
                <file_watch_threads>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </file_watch_threads>
            </qos>
        </domainparticipant_factory>
    </profiles>
<dds>

10.3. DomainParticipant profiles

The DomainParticipant profiles allow the definition of the configuration of DomainParticipants through XML files. These profiles are defined within the <participant> XML tags.

10.3.1. DomainParticipant XML attributes

The <participant> element has two attributes defined: profile_name and is_default_profile.

Name

Description

Use

profile_name

Sets the name under which the <participant> profile is registered in the DDS Domain,
so that it can be loaded later by the DomainParticipantFactory, as shown in
Loading and applying profiles.

Mandatory

is_default_profile

Sets the <participant> profile as the default profile. Thus, if a default profile
exists, it will be used when no other DomainParticipant profile is specified at the
DomainParticipant’s creation.

Optional

10.3.2. DomainParticipant configuration

The <participant> element has two child elements: <domainId> and <rtps>. All the DomainParticipant configuration options belong to the <rtps> element, except for the DDS DomainId which is defined by the <domainId> element. Below a list with the configuration XML elements is presented:

Name

Description

Values

Default

<domainId>

DomainId to be used by the DomainParticipant. See Profile based creation of a DomainParticipant.

uint32_t

0

<rtps>

Fast DDS DomainParticipant configurations.
See RTPS element type.

RTPS element type

10.3.2.1. RTPS element type

The following is a list with all the possible child XML elements of the <rtps> element. These elements allow the user to define the DomainParticipant configuration.

Name

Description

Values

Default

<name>

The DomainParticipant’s name.

string_255

<defaultUnicastLocatorList>

List of default reception unicast locators
for user data traffic (see
<metatrafficUnicastLocatorList>
defined in Builtin parameters).
It expects a LocatorListType.

<locator>

<defaultMulticastLocatorList>

List of default reception multicast
locators for user data traffic (see
<metatrafficMulticastLocatorList>
defined in Builtin parameters).
It expects a LocatorListType.

<locator>

<default_external_unicast_locators>

List of External Locators
to announce for the default user traffic of
this participant.

ExternalLocatorListType

<ignore_non_matching_locators>

Whether to ignore locators received on
announcements from other participants when
they don’t match with any of the locators
announced by this participant.

bool

false

<sendSocketBufferSize>

Size in bytes of the send socket buffer.
If the value is zero then Fast DDS will
use the system default socket size.

uint32_t

0

<listenSocketBufferSize>

Size in bytes of the reception socket
buffer. If the value is zero then
Fast DDS will use the system default
socket size.

uint32_t

0

<netmask_filter>

Participant’s netmask
filtering configuration.
See the Netmask filtering section.

NetmaskFilterKind

AUTO

<builtin>

builtin public data member of the
WireProtocolConfigQos class.
See the Builtin parameters section.

Builtin parameters

<port>

Allows defining the port and gains related
to the RTPS protocol. See the Port section.

Port

<participantID>

DomainParticipant’s identifier. Typically
it will be automatically generated by the
DomainParticipantFactory.

int32_t

0

<easy_mode_ip>

IP address of the remote discovery server
to connect to using Discovery Server Easy Mode.

string

Empty

<userTransports>

Transport descriptors to be used by the
DomainParticipant. See
Transport descriptors.

List <string>

<useBuiltinTransports>

Boolean field to indicate the system
whether the DomainParticipant will use the
default builtin transports
in addition to its <userTransports>.

bool

true

<builtinTransports>

Configuration option to determine which transports
will be instantiated if the useBuiltinTransports is
set to true. See Managing the Builtin Transports.

BuiltinTransportType

<propertiesPolicy>

Additional configuration properties.
See PropertyPolicyQos.

PropertiesPolicyType

<allocation>

Configuration regarding allocation behavior.
It expects a DomainParticipantAllocationType.

DomainParticipantAllocationType

<userData>

Additional information attached to the DomainParticipant
and transmitted with the discovery information.
See UserDataQosPolicy.

List <string>

Empty

<prefix>

DomainParticipant’s GuidPrefix_t identifies peers
running in the same process. Two participants with identical
8 first bytes on the GuidPrefix_t are considered to be
running in the same process, and therefore intra-process
delivery is used. See Intra-process delivery.

string

Empty

<builtin_controllers_sender_thread>

ThreadSettings for the builtin flow controllers sender thread.

ThreadSettings

<timed_events_thread>

ThreadSettings participant’s timed events thread.

ThreadSettings

<discovery_server_thread>

ThreadSettings for the discovery server thread.

ThreadSettings

<typelookup_service_thread>

ThreadSettings for the threads used by the builtin TypeLookup service
to discover unknown remote types.
See Remote Data Types Discovery.

ThreadSettings

<builtin_transports_reception_threads>

ThreadSettings for the builtin transports reception threads.

ThreadSettings

<security_log_thread>

ThreadSettings for the security log thread.

ThreadSettings

<flow_controller_descriptor_list>

Defined flow controller descriptors to be used by the
DomainParticipant. See Flow Controller Descriptors.

FlowControllersQos

Example

<?xml version="1.0" encoding="UTF-8" ?>
<dds>
    <profiles xmlns="http://www.eprosima.com">
        <participant profile_name="domainparticipant_profile_name">
            <domainId>4</domainId>
            <rtps>
                <name>DomainParticipant Name</name>

                <defaultUnicastLocatorList>
                    <!-- LOCATOR_LIST -->
                    <locator>
                        <udpv4>
                            <port>7400</port>
                            <address>192.168.1.41</address>
                        </udpv4>
                    </locator>
                </defaultUnicastLocatorList>

                <defaultMulticastLocatorList>
                    <!-- LOCATOR_LIST -->
                    <locator>
                        <udpv4>
                            <port>7400</port>
                            <address>192.168.2.41</address>
                        </udpv4>
                    </locator>
                </defaultMulticastLocatorList>

                <default_external_unicast_locators>
                    <!-- EXTERNAL_LOCATOR_LIST -->
                    <udpv4 externality="1" cost="0" mask="24">
                        <address>100.100.100.10</address>
                        <port>23456</port>
                    </udpv4>
                </default_external_unicast_locators>

                <ignore_non_matching_locators>true</ignore_non_matching_locators>

                <sendSocketBufferSize>8192</sendSocketBufferSize>

                <listenSocketBufferSize>8192</listenSocketBufferSize>

                <netmask_filter>ON</netmask_filter>

                <builtin>
                    <!-- BUILTIN -->
                </builtin>

                <port>
                    <portBase>7400</portBase>
                    <domainIDGain>200</domainIDGain>
                    <participantIDGain>10</participantIDGain>
                    <offsetd0>0</offsetd0>
                    <offsetd1>1</offsetd1>
                    <offsetd2>2</offsetd2>
                    <offsetd3>3</offsetd3>
                </port>

                <participantID>99</participantID>

                <userTransports>
                    <transport_id>TransportId1</transport_id>
                    <transport_id>TransportId2</transport_id>
                </userTransports>

                <useBuiltinTransports>false</useBuiltinTransports>

                <builtinTransports>DEFAULT</builtinTransports>

                <propertiesPolicy>
                    <!-- PROPERTIES_POLICY -->
                    <properties>
                        <property>
                            <name>Property1Name</name>
                            <value>Property1Value</value>
                            <propagate>false</propagate>
                        </property>
                    </properties>
                </propertiesPolicy>

                <allocation>
                    <!-- ALLOCATION -->
                </allocation>

                <userData>
                    <value>3.4.7.0.C</value>
                </userData>

                <prefix>72.61.73.70.66.61.72.6d.74.65.73.74</prefix>

                <builtin_controllers_sender_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </builtin_controllers_sender_thread>

                <timed_events_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </timed_events_thread>

                <discovery_server_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </discovery_server_thread>

                <typelookup_service_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </typelookup_service_thread>

                <builtin_transports_reception_threads>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </builtin_transports_reception_threads>

                <security_log_thread>
                    <scheduling_policy>-1</scheduling_policy>
                    <priority>0</priority>
                    <affinity>0</affinity>
                    <stack_size>-1</stack_size>
                </security_log_thread>

                <flow_controller_descriptor_list>
                    <flow_controller_descriptor>
                        <name>example_flow_controller</name>
                        <scheduler>FIFO</scheduler>
                        <max_bytes_per_period>4096</max_bytes_per_period>
                        <period_ms>500</period_ms>
                        <sender_thread>
                            <scheduling_policy>-1</scheduling_policy>
                            <priority>0</priority>
                            <affinity>0</affinity>
                            <stack_size>-1</stack_size>
                        </sender_thread>
                    </flow_controller_descriptor>
                </flow_controller_descriptor_list>
            </rtps>
        </participant>
    </profiles>
</dds>

Note

10.3.2.2. Builtin parameters

By calling the wire_protocol() member function of the DomainParticipantQos, it is possible to access the builtin public data member of the WireProtocolConfigQos class. This section specifies the available XML members for the configuration of this builtin parameters.

Name

Description

Values

Default

<discovery_config>

This is the main element within
which discovery-related
settings can be configured.
See Discovery.

discovery_config

<avoid_builtin_multicast>

Restricts multicast metatraffic
to PDP only.

bool

true

<use_WriterLivelinessProtocol>

Indicates whether to use the
DataWriterLiveliness protocol.

bool

true

<metatrafficUnicastLocatorList>

Metatraffic Unicast Locator List.

A set of <locator>
members.
See LocatorListType

<metatrafficMulticastLocatorList>

Metatraffic Multicast Locator List.

A set of <locator>
members.
See LocatorListType

<initialPeersList>

The list of IP-port address
pairs of all other
DomainParticipants with which
a DomainParticipant will
communicate. See
Initial peers

A set of <locator>
members.
See LocatorListType

<metatraffic_external_unicast_locators>

List of External Locators
to announce for the metatraffic of
this participant.

ExternalLocatorListType

<readerHistoryMemoryPolicy>

Memory policy for DataReaders.
See HistoryQosPolicyKind.

HistoryMemoryPolicy

PREALLOCATED

<writerHistoryMemoryPolicy>

Memory policy for DataWriters.
See HistoryQosPolicyKind.

HistoryMemoryPolicy

PREALLOCATED

<readerPayloadSize>

Maximum DataReader’s History
payload size. Allows to reserve
all the required memory at
DataReader initialization.
See MemoryManagementPolicy.

uint32_t

512

<writerPayloadSize>

Maximum DataWriter’s History
payload size. Allows to reserve
all the required memory at
DataWriter initialization.
See MemoryManagementPolicy.

uint32_t

512

<mutation_tries>

Number of different ports
to try if DataReader’s physical
port is already in use.

uint32_t

100

<flow_controller_name>

FlowControllersQos name.

string

Empty

Example

<builtin>
    <discovery_config>
        <discoveryProtocol>CLIENT</discoveryProtocol>

        <discoveryServersList>
            <locator>
                <udpv4>
                    <address>192.168.10.57</address>
                    <port>56542</port>
                </udpv4>
            </locator>
            <locator>
                <udpv4>
                    <address>192.168.10.58</address>
                    <port>24565</port>
                </udpv4>
            </locator>
        </discoveryServersList>

        <ignoreParticipantFlags>FILTER_DIFFERENT_HOST</ignoreParticipantFlags>

        <EDP>SIMPLE</EDP>

        <simpleEDP>
            <PUBWRITER_SUBREADER>true</PUBWRITER_SUBREADER>
            <PUBREADER_SUBWRITER>true</PUBREADER_SUBWRITER>
        </simpleEDP>

        <leaseDuration>
            <!-- DURATION -->
            <sec>20</sec>
        </leaseDuration>

        <leaseAnnouncement>
            <!-- DURATION -->
            <sec>3</sec>
        </leaseAnnouncement>

        <initialAnnouncements>
            <!-- INITIAL_ANNOUNCEMENTS -->
            <count>10</count>
            <period>
                <nanosec>50</nanosec>
            </period>
        </initialAnnouncements>

        <clientAnnouncementPeriod>
            <nanosec>250000000</nanosec>
        </clientAnnouncementPeriod>

        <static_edp_xml_config>file://filename1.xml</static_edp_xml_config>
        <static_edp_xml_config>file://filename2.xml</static_edp_xml_config>
        <static_edp_xml_config>file://filename3.xml</static_edp_xml_config>
    </discovery_config>

    <avoid_builtin_multicast>true</avoid_builtin_multicast>

    <use_WriterLivelinessProtocol>false</use_WriterLivelinessProtocol>

    <metatrafficUnicastLocatorList>
        <!-- LOCATOR_LIST -->
        <locator>
            <udpv4>
                <address>192.168.0.1</address>
            </udpv4>
        </locator>
    </metatrafficUnicastLocatorList>

    <metatrafficMulticastLocatorList>
        <!-- LOCATOR_LIST -->
        <locator>
            <udpv4>
                <address>192.168.0.1</address>
            </udpv4>
        </locator>
    </metatrafficMulticastLocatorList>

    <initialPeersList>
        <!-- LOCATOR_LIST -->
        <locator>
            <udpv4>
                <address>192.168.0.1</address>
            </udpv4>
        </locator>
    </initialPeersList>

    <metatraffic_external_unicast_locators>
        <!-- EXTERNAL_LOCATOR_LIST -->
        <udpv4 externality="1" cost="0" mask="24">
            <address>100.100.100.10</address>
            <port>34567</port>
        </udpv4>
    </metatraffic_external_unicast_locators>

    <readerHistoryMemoryPolicy>PREALLOCATED_WITH_REALLOC</readerHistoryMemoryPolicy>

    <writerHistoryMemoryPolicy>PREALLOCATED_WITH_REALLOC</writerHistoryMemoryPolicy>

    <readerPayloadSize>512</readerPayloadSize>

    <writerPayloadSize>512</writerPayloadSize>

    <mutation_tries>55</mutation_tries>

</builtin>
10.3.2.2.1. discovery_config

Through the <discovery_config> element, Fast DDS allows the configuration of the discovery mechanism via an XML file. Please refer to the Discovery section for more detail on the various types of discovery mechanisms and configurable settings.

Name

Description

Values

Default

<discoveryProtocol>

Indicates which discovery protocol
the DomainParticipant will use.
See Discovery mechanisms. If not set to
SIMPLE or NONE, <discoveryServersList>
element would be used.

SIMPLE

SIMPLE

CLIENT

SERVER

BACKUP

SUPER_CLIENT

NONE

<discoveryServersList>

Describes locators of servers from which
it receives only the discovery information
they require to establish communication
with matching endpoints.
It expects a LocatorListType.

<locator>

<ignoreParticipantFlags>

Restricts metatraffic using several
filtering criteria. See Ignore Participant flags.

ignoreParticipantFlags

NO_FILTER

<EDP>

If set to SIMPLE, <simpleEDP>
element would be used.
If set to STATIC, EDPStatic will be
performed, configured with the contents
of the XML file set in <static_edp_xml_config>.
See Discovery.

SIMPLE

SIMPLE

STATIC

<simpleEDP>

Attributes of the Simple Discovery
Protocol. See Simple EDP Attributes.

simpleEDP

<leaseDuration>

Indicates how long the DomainParticipant
should consider remote DomainParticipants
alive. See Lease Duration.

DurationType

20s

<leaseAnnouncement>

The period for the DomainParticipant to
send its discovery message to all other
discovered DomainParticipants as well as
to all Multicast ports. See Announcement Period.

DurationType

3s

<initialAnnouncements>

Allows the user to configure the number
and period of the DomainParticipant’s initial
discovery messages. See Initial Announcements.

Initial Announcements

<clientAnnouncementPeriod>

The period for the DomainParticipant to
send its Discovery Message to its servers
and check for EDP endpoints matching.

DurationType

450 ms

<static_edp_xml_config>

The XML filename(s) with the static EDP
configuration. Only necessary if
the <EDP> member is set to
STATIC. See STATIC Discovery Settings.

List <string>

ignoreParticipantFlags

Possible values

Description

NO_FILTER

All Discovery traffic is processed.

FILTER_DIFFERENT_HOST

Discovery traffic from another host is discarded.

FILTER_DIFFERENT_PROCESS

Discovery traffic from another process on the same host is discarded.

FILTER_SAME_PROCESS

Discovery traffic from DomainParticipant’s own process is discarded.

This option also supports the OR (|) operator to filter discovery traffic from other configurations. For instance, FILTER_DIFFERENT_PROCESS|FILTER_SAME_PROCESS value discards discovery traffic from the DomainParticipant’s own host.

simpleEDP

Name

Description

Values

Default

<PUBWRITER_SUBREADER>

Indicates if the participant must use
Publication DataWriter and Subscription DataReader.

bool

true

<PUBREADER_SUBWRITER>

Indicates if the participant must use
Publication DataReader and Subscription DataWriter.

bool

true

Initial Announcements

Name

Description

Values

Default

<count>

Number of initial discovery messages to send at the period specified by
<period>. After these announcements, the DomainParticipant will continue
sending its discovery messages at the <leaseAnnouncement> rate.

uint32_t

5

<period>

The period for the DomainParticipant to send its discovery messages.

DurationType

100 ms

10.3.2.3. Port Configuration

According to the RTPS standard (Section 9.6.1.1), the RTPSParticipants’ discovery traffic unicast listening ports are calculated using the following equation: \(7400 + 250 * DomainId + 10 + 2 * ParticipantId\). Therefore the following parameters can be specified:

Name

Description

Values

Default

<portBase>

Base port.

uint16_t

7400

<domainIDGain>

Gain in DomainId.

uint16_t

250

<participantIDGain>

Gain in participant_id.

uint16_t

2

<offsetd0>

Multicast metadata offset.

uint16_t

0

<offsetd1>

Unicast metadata offset.

uint16_t

10

<offsetd2>

Multicast user data offset.

uint16_t

1

<offsetd3>

Unicast user data offset.

uint16_t

11

Warning

Changing these default parameters may break compatibility with other RTPS compliant implementations, as well as with other Fast DDS applications with default port settings.

10.3.2.4. ParticipantAllocationType

The ParticipantAllocationType defines the <allocation> element, which allows setting of the parameters related with the allocation behavior on the DomainParticipant. Please refer to ParticipantResourceLimitsQos for a detailed documentation on DomainParticipants allocation configuration.

Name

Description

Values

<remote_locators>

Defines the limits for the remote locators’ collections.
See RemoteLocatorsAllocationAttributes.

Remote Locators Allocations

<total_participants>

DomainParticipant Allocation Configuration to specify the
total number of DomainParticipants in the domain
(local and remote). See
ResourceLimitedContainerConfig.

Allocation Configuration

<total_readers>

DomainParticipant Allocation Configuration to specify the
total number of DataReader on each DomainParticipant
(local and remote). See
ResourceLimitedContainerConfig.

Allocation Configuration

<total_writers>

DomainParticipant Allocation Configuration related to the
total number of DataWriters on each DomainParticipant
(local and remote). See ResourceLimitedContainerConfig.

Allocation Configuration

<max_partitions>

Maximum size of the partitions submessage.
Set to zero for no limit.

uint32_t

<max_user_data>

Maximum size of the user data submessage.
Set to zero for no limit.

uint32_t

<max_properties>

Maximum size of the properties submessage.
Set to zero for no limit.

uint32_t

<send_buffers>

Allocation behaviour for the send buffer
manager.

Send buffers

Example

<allocation>
    <remote_locators>
        <max_unicast_locators>4</max_unicast_locators>
        <max_multicast_locators>1</max_multicast_locators>
    </remote_locators>

    <total_participants>
        <initial>0</initial>
        <maximum>0</maximum>
        <increment>1</increment>
    </total_participants>

    <total_readers>
        <initial>0</initial>
        <maximum>0</maximum>
        <increment>1</increment>
    </total_readers>

    <total_writers>
        <initial>0</initial>
        <maximum>0</maximum>
        <increment>1</increment>
    </total_writers>

    <max_partitions>256</max_partitions>

    <max_user_data>256</max_user_data>

    <max_properties>512</max_properties>

    <send_buffers>
        <preallocated_number>127</preallocated_number>
        <dynamic>true</dynamic>
        <network_buffers_config>
            <initial>16</initial>
            <maximum>0</maximum>
            <increment>16</increment>
        </network_buffers_config>
    </send_buffers>

    <!-- content_filter cannot be configured using XML (yet) -->
</allocation>
10.3.2.4.1. Remote Locators Allocations

Name

Description

Values

Default

<max_unicast_locators>

Maximum number of unicast locators expected on a
remote entity. It is recommended to use the maximum
number of network interfaces available on the machine
on which DomainParticipant is running.
See RemoteLocatorsAllocationAttributes.

uint32_t

4

<max_multicast_locators>

Maximum number of multicast locators expected on a
remote entity. May be set to zero to disable multicast
traffic. See RemoteLocatorsAllocationAttributes.

uint32_t

1

10.3.2.4.2. Send buffers

Name

Description

Values

Default

<preallocated_number>

Initial number of send buffers to allocate. See
SendBuffersAllocationAttributes.

uint32_t

0

<dynamic>

Whether the number of send buffers is allowed to
grow. See SendBuffersAllocationAttributes.

bool

false

<network_buffers_config>

Network buffer Allocation Configuration to specify the
number of network buffers to be allocated for each
send buffer. See ResourceLimitedContainerConfig.

Allocation Configuration

(16, inf, 16)

Note

The default value 0 of <preallocated_number> will perform an initial guess of the number of buffers required, based on the number of threads from which a send operation could be started. So it does not mean there are no buffers, instead it would use the maximum amount of buffers available. On the contrary, <network_buffers_config> will default to an initial number of 16 buffers, with an infinite maximum and an increment of 16 buffers per send buffer. An initial value of 0 will imply more dynamic allocations, especially at the beginning of the execution. In case of doubt, it should be left to the default values.

10.4. DataWriter profiles

The DataWriter profiles allow for configuring DataWriters from an XML file. These profiles are defined within the <data_writer> XML tags.

10.4.1. DataWriter XML attributes

The <data_writer> element has two attributes defined: profile_name and is_default_profile.

Name

Description

Use

profile_name

Sets the name under which the <data_writer> profile is registered in the DDS Domain,
so that it can be loaded later by the DomainParticipant, as shown in
Loading and applying profiles.

Mandatory

is_default_profile

Sets the <data_writer> profile as the default profile. Thus, if a default profile
exists, it will be used when no other DataWriter profile is specified at the
DataWriter’s creation.

Optional

10.4.2. DataWriter configuration

The DataWriter configuration is performed through the XML elements listed in the following table.

Name

Description

Values

Default

<topic>

TopicType configuration of the DataWriter.

TopicType

<qos>

DataWriter QoS configuration.

QoS

<times>

It configures some time related parameters
of the DataWriter.

WriterTimes

<unicastLocatorList>

List of input unicast locators.
It expects a LocatorListType.

<locator>

<multicastLocatorList>

List of input multicast locators.
It expects a LocatorListType.

<locator>

<external_unicast_locators>

List of External Locators
to announce for the communication
with this DataWriter.

ExternalLocatorListType

<ignore_non_matching_locators>

Whether to ignore locators received on
announcements from other entities when
they don’t match with any of the locators
announced by this DataWriter.

bool

false

<historyMemoryPolicy>

Memory allocation kind for DataWriter’s
history. See HistoryQosPolicyKind.

HistoryMemoryPolicy

PREALLOCATED

<propertiesPolicy>

Additional configuration properties.

PropertiesPolicyType

<userDefinedID>

Used for EDPStatic.

int16_t

-1

<entityID>

Sets the entity_id of the RTPSEndpointQos
class.

int16_t

-1

<matchedSubscribersAllocation>

Sets the limits of the collection of matched
DataReaders. See
ParticipantResourceLimitsQos.

Allocation Configuration

Example

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <data_writer profile_name="datawriter_profile_name">
            <topic>
                <historyQos>
                    <kind>KEEP_LAST</kind>
                </historyQos>
            </topic>

            <qos>
                <!-- QOS -->
            </qos>

            <times> <!-- writerTimesType -->
                <initial_heartbeat_delay>
                    <nanosec>12</nanosec>
                </initial_heartbeat_delay>

                <heartbeat_period>
                    <sec>3</sec>
                </heartbeat_period>

                <nack_response_delay>
                    <nanosec>5</nanosec>
                </nack_response_delay>

                <nack_supression_duration>
                    <sec>0</sec>
                </nack_supression_duration>
            </times>

            <unicastLocatorList>
                <!-- LOCATOR_LIST -->
                <locator>
                    <udpv4>
                        <address>192.168.0.1</address>
                    </udpv4>
                </locator>
            </unicastLocatorList>

            <multicastLocatorList>
                <!-- LOCATOR_LIST -->
                <locator>
                    <udpv4>
                        <address>192.168.0.1</address>
                    </udpv4>
                </locator>
            </multicastLocatorList>

            <external_unicast_locators>
                <!-- EXTERNAL_LOCATOR_LIST -->
                <udpv4 externality="1" cost="0" mask="24">
                    <address>100.100.100.10</address>
                    <port>12345</port>
                </udpv4>
            </external_unicast_locators>

            <ignore_non_matching_locators>true</ignore_non_matching_locators>

            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>

            <!-- PROPERTIES_POLICY -->
            <propertiesPolicy>
                <properties>
                    <property>
                        <name>PropertyName</name>
                        <value>PropertyValue</value>
                    </property>
                </properties>
            </propertiesPolicy>

            <userDefinedID>55</userDefinedID>

            <entityID>66</entityID>

            <matchedSubscribersAllocation>
                <initial>0</initial>
                <maximum>0</maximum>
                <increment>1</increment>
            </matchedSubscribersAllocation>

            <!-- reader_filters_allocation cannot be configured using XML (yet) -->
        </data_writer>
    </profiles>
</dds>

Note

10.4.2.1. WriterTimes

These parameters are included within RTPSReliableWriterQos in the WriterTimes structure.

Name

Description

Values

Default

<initial_heartbeat_delay>

Initial heartbeat delay.

DurationType

12 ms

<heartbeat_period>

Periodic heartbeat period.

DurationType

3 s

<nack_response_delay>

Delay to apply to the response of an ACKNACK message.

DurationType

5 ms

<nack_supression_duration>

This time allows the DataWriter to ignore NACK
messages for a given period of time right after
the data has been sent.

DurationType

0 ms

10.5. DataReader profiles

The DataReader profiles allow declaring DataReaders from an XML file. These profiles are defined within the <data_reader> XML tags.

10.5.1. DataReader XML attributes

The <data_reader> element has two attributes defined: profile_name and is_default_profile.

Name

Description

Use

profile_name

Sets the name under which the <data_reader> profile is registered in the DDS Domain,
so that it can be loaded later by the DomainParticipant, as shown in
Loading and applying profiles.

Mandatory

is_default_profile

Sets the <data_reader> profile as the default profile. Thus, if a default profile
exists, it will be used when no other DataReader profile is specified at the
DataReader’s creation.

Optional

10.5.2. DataReader configuration

The DataReader configuration is performed through the XML elements listed in the following table.

Name

Description

Values

Default

<topic>

TopicType configuration of the DataReader.

TopicType

<qos>

Subscriber QoS configuration.

QoS

<times>

It allows configuring some time related
parameters of the DataReader.

ReaderTimes

<unicastLocatorList>

List of input unicast locators.
It expects a LocatorListType.

List of LocatorListType

<multicastLocatorList>

List of input multicast locators.
It expects a LocatorListType.

List of LocatorListType

<external_unicast_locators>

List of External Locators
to announce for the communication
with this DataReader.

ExternalLocatorListType

<ignore_non_matching_locators>

Whether to ignore locators received on
announcements from other entities when
they don’t match with any of the locators
announced by this DataReader.

bool

false

<expects_inline_qos>

It indicates if QoS is expected inline.

bool

false

<historyMemoryPolicy>

Memory allocation kind for DataReaders’s
history.

HistoryMemoryPolicy

PREALLOCATED

<propertiesPolicy>

Additional configuration properties.

PropertiesPolicyType

<userDefinedID>

Used for StaticEndpointDiscovery.

int16_t

-1

<entityID>

Set the entity_id of the RTPSEndpointQos
class.

int16_t

-1

<matchedPublishersAllocation>

Sets the limits of the collection of matched
DataWriters. See
ParticipantResourceLimitsQos.

Allocation Configuration

Example

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <data_reader profile_name="data_reader_profile_name">
            <topic>
                <historyQos>
                    <kind>KEEP_LAST</kind>
                </historyQos>
            </topic>

            <qos>
                <!-- QOS -->
            </qos>

            <times> <!-- readerTimesType -->
                <initial_acknack_delay>
                    <nanosec>70</nanosec>
                </initial_acknack_delay>

                <heartbeat_response_delay>
                    <nanosec>5</nanosec>
                </heartbeat_response_delay>
            </times>

            <unicastLocatorList>
                <!-- LOCATOR_LIST -->
                <locator>
                    <udpv4>
                        <address>192.168.0.1</address>
                    </udpv4>
                </locator>
            </unicastLocatorList>

            <multicastLocatorList>
                <!-- LOCATOR_LIST -->
                <locator>
                    <udpv4>
                        <address>192.168.0.1</address>
                    </udpv4>
                </locator>
            </multicastLocatorList>

            <external_unicast_locators>
                <!-- EXTERNAL_LOCATOR_LIST -->
                <udpv4 externality="1" cost="0" mask="24">
                    <address>100.100.100.10</address>
                    <port>12345</port>
                </udpv4>
            </external_unicast_locators>

            <ignore_non_matching_locators>true</ignore_non_matching_locators>

            <expects_inline_qos>true</expects_inline_qos>

            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>

            <!-- PROPERTIES_POLICY -->
            <propertiesPolicy>
                <properties>
                    <property>
                        <name>PropertyName</name>
                        <value>PropertyValue</value>
                    </property>
                </properties>
            </propertiesPolicy>

            <userDefinedID>55</userDefinedID>

            <entityID>66</entityID>

            <matchedPublishersAllocation>
                <initial>0</initial>
                <maximum>0</maximum>
                <increment>1</increment>
            </matchedPublishersAllocation>
        </data_reader>
    </profiles>
</dds>

Note

10.5.2.1. ReaderTimes

These parameters are included within RTPSReliableReaderQos in the ReaderTimes structure.

Name

Description

Values

Default

<initial_acknack_delay>

Initial ACKNACK delay.

DurationType

70 ms

<heartbeat_response_delay>

Response time delay when receiving a Heartbeat.

DurationType

5 ms

10.6. Topic profiles

The topic profiles allow for configuring Topic from an XML file. These profiles are defined within the <topic> XML tags.

10.6.1. Topic XML attributes

The <topic> element has two attributes defined: profile_name and is_default_profile.

Name

Description

Use

profile_name

Sets the name under which the <topic> profile is registered in the DDS Domain,
so that it can be loaded later by the DataWriter or the DataReader

Mandatory

is_default_profile

Sets the <topic> profile as the default profile. Thus, if a default profile
exists, it will be used when no other Topic profile is specified at the
Topic’s creation.

Optional

10.6.2. Topic configuration

This XML element allows the configuration of the TopicQos.

Name

Description

Values

<historyQos>

It controls the behavior of Fast DDS
when the value of an instance changes
before it is finally communicated to
some of its existing DataReaders.

HistoryQoS

<resourceLimitsQos>

It controls the resources that Fast DDS
can use in order to meet the
requirements imposed by the application
and other QoS settings.

ResourceLimitsQos

Example

<topic profile_name="topic_example">
    <historyQos>
        <kind>KEEP_LAST</kind>
        <depth>20</depth>
    </historyQos>
    <resourceLimitsQos>
        <max_samples>5</max_samples>
        <max_instances>2</max_instances>
        <max_samples_per_instance>1</max_samples_per_instance>
        <allocated_samples>20</allocated_samples>
        <extra_samples>10</extra_samples>
    </resourceLimitsQos>
</topic>

10.7. Transport descriptors

This section defines the XML elements available for configuring the transport layer parameters in Fast DDS. These elements are defined within the XML tag <transports_descriptors>. The <transport_descriptors> can contain one or more <transport_descriptor> XML elements. Each <transport_descriptor> element defines a configuration for a specific type of transport protocol. Each of these <transport_descriptor> elements are uniquely identified by a transport ID with the <transport_id> XML tag. Once the user defines a valid <transports_descriptor>, i.e. defines the transport layer parameters, these can be loaded into the XML profile of the DomainParticipant using the <transport_id> XML tag. An example of how to load the <transport_descriptor> into the XML profile of the DomainParticipant is found in DomainParticipant profiles.

The following table lists all the available XML elements that can be defined within the <transport_descriptor> element for the configuration of the transport layer. A more detailed explanation of each of these elements can be found in Transport Layer.

Name

Description

Values

Default

<transport_id>

Unique name to identify each transport descriptor.

string

<type>

Type of the transport descriptor.

UDPv4

UDPv4

UDPv6

TCPv4

TCPv6

SHM

<sendBufferSize>

Size in bytes of the send socket buffer.
If the value is zero then Fast DDS will use
the system default socket size.

uint32_t

0

<receiveBufferSize>

Size in bytes of the reception socket
buffer. If the value is zero then Fast DDS
will use the system default socket size.

uint32_t

0

<maxMessageSize>

The maximum size in bytes of the transport’s
message buffer.

uint32_t

65500

<maxInitialPeersRange>

Number of channels opened with each initial
remote peer.

uint32_t

4

<netmask_filter>

Transport’s Netmask filtering
configuration.

OFF

AUTO

AUTO

ON

<interfaces>

Allows defining an Interfaces configuration.

Interfaces configuration

<interfaceWhiteList>

Allows defining an interfaces Whitelist.

Whitelist

<TTL>

Time To Live (UDP only). See
UDP Transport.

uint8_t

1

<non_blocking_send>

Whether to set the non-blocking send mode on
the socket (NOT available for SHM type). See
UDPTransportDescriptor and
TCPTransportDescriptor.

bool

false

<output_port>

Port used for output bound.
If this field isn’t defined, the output port
will be random (UDP only).

uint16_t

0

<wan_addr>

Public WAN address when using TCPv4
transports. This field is optional if the
transport doesn’t need to define a WAN
address (TCPv4 only).

IPv4 formatted
string:
XXX.XXX.XXX.XXX

<keep_alive_frequency_ms>

Frequency in milliseconds for sending RTCP
keep-alive requests (TCP only).

uint32_t

50000

<keep_alive_timeout_ms>

Time in milliseconds since the last
keep-alive request was sent to consider a
connection as broken (TCP only).

uint32_t

10000

<max_logical_port>

The maximum number of logical ports to try
during RTCP negotiations (TCP only).

uint16_t

100

<logical_port_range>

The maximum number of logical ports per
request to try during RTCP negotiations
(TCP only).

uint16_t

20

<logical_port_increment>

Increment between logical ports to try during
RTCP negotiation
(TCP only).

uint16_t

2

<listening_ports>

Local port to work as TCP acceptor for input
connections. If not set, the transport will
work as TCP client only. If set to 0, an
available port will be automatically assigned
(TCP only).

List <uint16_t>

<tls>

Allows to define TLS related parameters and
options (TCP only).

TLS Configuration

<calculate_crc>

Calculates the Cyclic Redundancy Code (CRC)
for error control (TCP only).

bool

true

<check_crc>

Check the CRC for error control (TCP
only).

bool

true

<enable_tcp_nodelay>

Socket option for disabling the Nagle
algorithm. (TCP only).

bool

false

<tcp_negotiation_timeout>

Time to wait for logical port negotiation (in ms)
(TCP only).

uint32_t

0

<segment_size>

Size (in bytes) of the shared-memory segment.
(Optional, SHM only).

uint32_t

262144

<port_queue_capacity>

Capacity (in number of messages) available to
every Listener (Optional, SHM only).

uint32_t

512

<healthy_check_timeout_ms>

Maximum time-out (in milliseconds) used when
checking whether a Listener is alive
(Optional, SHM only).

uint32_t

1000

<rtps_dump_file>

Complete path (including file) where RTPS
messages will be stored for debugging
purposes. An empty string indicates no trace
will be performed (Optional, SHM only).

string

Empty

The following XML code shows an example of transport protocol configuration using all configurable parameters. More examples of transports descriptors can be found in the Transport Layer section.

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>my_udpv4_transport</transport_id>
                <type>UDPv4</type>
                <sendBufferSize>8192</sendBufferSize>
                <receiveBufferSize>8192</receiveBufferSize>
                <maxMessageSize>16384</maxMessageSize>
                <maxInitialPeersRange>100</maxInitialPeersRange>
                <netmask_filter>AUTO</netmask_filter>
                <interfaces>
                    <allowlist>
                        <interface name="wlp59s0" netmask_filter="ON"/>
                    </allowlist>
                    <blocklist>
                        <interface name="127.0.0.1"/>
                        <interface name="docker0"/>
                    </blocklist>
                </interfaces>
                <interfaceWhiteList>
                    <address>192.168.1.41</address>
                    <interface>lo</interface>
                </interfaceWhiteList>
                <TTL>250</TTL>
                <non_blocking_send>false</non_blocking_send>
                <output_port>5101</output_port>
                <wan_addr>80.80.55.44</wan_addr>
                <keep_alive_frequency_ms>5000</keep_alive_frequency_ms>
                <keep_alive_timeout_ms>25000</keep_alive_timeout_ms>
                <max_logical_port>9000</max_logical_port>
                <logical_port_range>100</logical_port_range>
                <logical_port_increment>2</logical_port_increment>
                <listening_ports>
                    <port>5100</port>
                    <port>5200</port>
                </listening_ports>
                <tls><!-- TLS Section --></tls>
                <calculate_crc>false</calculate_crc>
                <check_crc>false</check_crc>
                <enable_tcp_nodelay>false</enable_tcp_nodelay>
                <segment_size>262144</segment_size>
                <port_queue_capacity>512</port_queue_capacity>
                <healthy_check_timeout_ms>1000</healthy_check_timeout_ms>
                <rtps_dump_file>rtsp_messages.log</rtps_dump_file>
            </transport_descriptor>
        </transport_descriptors>
    </profiles>
</dds>

Note

The Real-time Transport Control Protocol (RTCP) is the control protocol for communications with RTPS over TCP/IP connections.

10.7.1. TLS Configuration

Fast DDS provides mechanisms to configure the Transport Layer Security (TLS) protocol parameters through the <tls> XML element of its <transport_descriptor>. Please, refer to TLS over TCP for a detailed explanation of the entire TLS configuration in Fast DDS. More information on how to set up secure communication in Fast DDS can be found in the Security section.

Warning

For the full understanding of this section, a basic knowledge of network security in terms of SSL/TLS, Certificate Authority (CA), Public Key Infrastructure (PKI), and Diffie-Hellman is required; encryption protocols are not explained in detail.

The full list of available XML elements that can be defined within the <tls> element to configure the TLS protocol are listed in the following table:

Name

Description

Values

Default

<password>

Password of the <private_key_file> or
<rsa_private_key_file> if provided.

string

<private_key_file>

Path to the private key certificate file.

string

<rsa_private_key_file>

Path to the private key RSA certificate file.

string

<cert_chain_file>

Path to the public certificate chain file.

string

<tmp_dh_file>

Path to the Diffie-Hellman parameters file

string

<verify_file>

Path to the Certification Authority (CA) file.

string

<verify_mode>

Establishes the verification mode mask. Several
verification options can be combined in the same
<transport_descriptor>.

VERIFY_NONE

VERIFY_PEER

VERIFY_FAIL_IF_NO_PEER_CERT

VERIFY_CLIENT_ONCE

<options>

Establishes the SSL Context options mask. Several
options can be combined in the same
<transport_descriptor>.

DEFAULT_WORKAROUNDS

NO_COMPRESSION

NO_SSLV2

NO_SSLV3

NO_TLSV1

NO_TLSV1_1

NO_TLSV1_2

NO_TLSV1_3

SINGLE_DH_USE

<verify_paths>

Paths where the system will look for verification
files.

List <string>

<verify_depth>

Maximum allowed depth to verify intermediate
certificates.

uint32_t

<default_verify_path>

Specifies whether the system will look on the
default paths for the verification files.

bool

false

<handshake_role>

Role that the transport will take on handshaking.
On default, the acceptors act as SERVER and the
connectors as CLIENT.

DEFAULT

DEFAULT

SERVER

CLIENT

<server_name>

server name or host name required in case Server Name Indication (SNI) is used.

string

An example of TLS protocol parameter configuration is shown below.

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>Test</transport_id>
                <type>TCPv4</type>
                <tls>
                    <password>Password</password>
                    <private_key_file>Key_file.pem</private_key_file>
                    <rsa_private_key_file>RSA_file.pem</rsa_private_key_file>
                    <cert_chain_file>Chain.pem</cert_chain_file>
                    <tmp_dh_file>DH.pem</tmp_dh_file>
                    <verify_file>verify.pem</verify_file>
                    <verify_mode>
                        <verify>VERIFY_PEER</verify>
                    </verify_mode>
                    <options>
                        <option>NO_TLSV1</option>
                        <option>NO_TLSV1_1</option>
                    </options>
                    <verify_paths>
                        <verify_path>Path1</verify_path>
                        <verify_path>Path2</verify_path>
                        <verify_path>Path3</verify_path>
                    </verify_paths>
                    <verify_depth>55</verify_depth>
                    <default_verify_path>true</default_verify_path>
                    <handshake_role>SERVER</handshake_role>
                    <server_name>my_server.com</server_name>
                </tls>
            </transport_descriptor>
<!-->
    </profiles>

10.8. Intra-process delivery profiles

This section defines the XML elements available for configuring the Intra-process delivery settings parameters in Fast DDS. These elements are defined within the XML tag <library_settings>.

10.8.1. Intra-process delivery configuration

The Intra-process delivery configuration is performed through the XML elements listed in the following table.

Name

Description

Values

Default

<intraprocess_delivery>

Speed up communications between entities within the same process by avoiding
any of the overhead involved in the transport layer.

OFF
USER_DATA_ONLY
FULL

OFF

Example

    <library_settings>
        <intraprocess_delivery>FULL</intraprocess_delivery> <!-- OFF | USER_DATA_ONLY | FULL -->
    </library_settings>

10.9. Log profiles

eProsima Fast DDS allows for registering and configuring Log consumers using XML configuration files. Please refer to Logging for more information on Fast DDS extensible Logging built-in module. The logging profiles are defined within the <log> XML tags. The <log> element has two child elements: <use_default> and <consumer>. These are described in the following table.

Name

Description

Values

Default

<use_default>

If set to FALSE, a call to Log::ClearConsumers() is
Log::ClearConsumers() is
performed. See Register Consumers.

bool

true

<consumer>

Defines the class and configuration of the consumer to
be registered. Multiple consumers can be registered
this way. See Consumers.

ConsumerDataType

<thread_settings>

ThreadSettings for the logging thread.

ThreadSettings

The following constitutes an example of an XML configuration file that sets the Log to use one StdoutConsumer, one StdoutErrConsumer, and one FileConsumer:

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <log>
        <!--
        Clear consumers
        -->
        <use_default>false</use_default>

        <!--
        StdoutConsumer does not have any properties
        -->
        <consumer>
            <class>StdoutConsumer</class>
        </consumer>

        <!--
        StdoutErrConsumer with threshold set to Log::Kind::Error
        -->
        <consumer>
            <class>StdoutErrConsumer</class>
            <property>
                <name>stderr_threshold</name>
                <value>Log::Kind::Error</value>
            </property>
        </consumer>

        <!--
        FileConsumer openning "execution.log" in append mode
        -->
        <consumer>
            <class>FileConsumer</class>
            <property>
                <name>filename</name>
                <value>execution.log</value>
            </property>
            <property>
                <name>append</name>
                <value>true</value>
            </property>
        </consumer>

        <!--
        ThreadSettings for the log's consumer thread
        -->
        <thread_settings>
            <scheduling_policy>-1</scheduling_policy>
            <priority>0</priority>
            <affinity>0</affinity>
            <stack_size>-1</stack_size>
        </thread_settings>
    </log>
</dds>

10.9.1. ConsumerDataType

Name

Description

Values

<class>

The class of the consumer.

StdoutConsumer

StdoutErrConsumer

FileConsumer

<property>

This element is used to configure the log consumer and only applies
if <class> is set to StdoutErrConsumer or FileConsumer.

PropertyType

10.9.2. PropertyType

Name

Description

Values

Default

<name>

Name of the property to be configured.

filename

append

stderr_threshold

<value>

The value of the property.

  • If <name> is set to filename, then this
    element contains the name of the log file. This
    property only applies if <class> is set to
    FileConsumer

string

output.log

  • If <name> is set to append, then this
    element defines whether the consumer should, upon
    creation, open the file for appending or
    overriding. This property only applies if
    <class> is set to FileConsumer

Boolean

false

  • If <name> is set to stderr_threshold, then
    this element defines the threshold used by the
    Log consumers.
    This property only applies if <class> is set
    to StdoutErrConsumer

Log::Kind

Log::Kind::Warning

10.10. Dynamic Types profiles

Fast DDS supports the implementation of Dynamic Language Binding by defining them through XML files. Thus the topic data types can be modified without the need to modify the source code of the DDS application.

10.10.1. XML Structure

The definition of data type profiles in the XML file is done with the types tag. Each types element can contain one or more Type definitions. Defining several types within a types element or a single type for each types element has the same result. Below, an example of a stand-alone types definition via XML is shown.

<types xmlns="http://www.eprosima.com">
    <type>
        <!-- Type definition -->
    </type>
    <type>
        <!-- Type definition -->
        <!-- Type definition -->
    </type>
</types>

Note

For more information on the difference between stand-alone and rooted definitions please refer to section Rooted vs Standalone profiles definition.

10.10.2. Type definition

Below, the types supported by eProsima Fast DDS are presented. For further information about the supported Dynamic Language Binding, please, refer to Supported Types. For each type listed below, an example of how to build the type’s XML profile is provided.

10.10.2.1. Member types

Member types are defined as any type that can belong to a Struct or a Union, or be aliased by a Alias. These can be defined by the <member> XML tag. A member can be annotated as key (equivalent of the IDL’s @key) by setting the key attribute to "true".

<member name="my_long" type="int32" key="true"/>
10.10.2.2. Primitive types

Primitive types are built-in types and they should be declared as members of an aggregated type (Structure Types or Union Types). Primitive types are declared by attribute type and the possible values are listed in the table below. Please, refer to Primitive Types for more information on primitive types.

boolean

byte

char8

char16

int32

uint32

int8

uint8

int16

uint16

int64

uint64

float32

float64

float128

All of them are declared as follows:

<struct name="PrimitivesStruct">
    <member name="my_bool" type="boolean"/>
    <member name="my_octet" type="byte"/>
    <member name="my_char" type="char8"/>
    <member name="my_wchar" type="char16"/>
    <member name="my_long" type="int32"/>
    <member name="my_ulong" type="uint32"/>
    <member name="my_int8" type="int8"/>
    <member name="my_uint8" type="uint8"/>
    <member name="my_short" type="int16"/>
    <member name="my_ushort" type="uint16"/>
    <member name="my_longlong" type="int64"/>
    <member name="my_ulonglong" type="uint64"/>
    <member name="my_float" type="float32"/>
    <member name="my_double" type="float64"/>
    <member name="my_longdouble" type="float128"/>
</struct>
struct PrimitivesStruct
{
    boolean my_bool;
    octet my_octet;
    char my_char;
    wchar my_wchar;
    long my_long;
    unsigned long my_ulong;
    int8 my_int8;
    uint8 my_uint8;
    short my_short;
    unsigned short my_ushort;
    long long my_longlong;
    unsigned long long my_ulonglong;
    float my_float;
    double my_double;
    long double my_longdouble;
};
10.10.2.3. String Types

String types should be defined as members of an aggregated type (Structure Types or Union Types). String types are defined with attribute type set to string or wstring. An optional attribute stringMaxLength might used to set a maximum length for the string collection. Please, refer to String Types for more information on string types.

<struct name="StringsStruct">
    <member name="my_string" type="string"/>
    <member name="my_wstring" type="wstring"/>
    <member name="my_bounded_string" type="string" stringMaxLength="41925"/>
    <member name="my_bounded_wstring" type="wstring" stringMaxLength="20925"/>
</struct>
struct StringsStruct
{
    string my_string;
    wstring my_wstring;
    string<41925> my_bounded_string;
    wstring<20925> my_bounded_wstring;
};
10.10.2.4. Enumeration Types

Enumeration types are defined using the <enum> tag. Attribute name and at least one <enumerator> child element are mandatory. Enumeration literals are defined using the <enumerator> tag with mandatory attribute name. Optionally, unsigned integer attribute value might be added to set a specific value for the enumeration literal.

Note

value attribute is equivalent to @value builtin annotation.

Please, refer to Enumeration Types for more information on enumeration types.

<enum name="MyEnum">
    <enumerator name="A" value="0"/>
    <enumerator name="B" value="1"/>
    <enumerator name="C"/>
</enum>

<struct name="EnumStruct">
    <member name="my_enum" type="nonBasic" nonBasicTypeName="MyEnum"/>
</struct>
enum MyEnum
{
    A,
    B,
    C
};

struct EnumStruct
{
    MyEnum my_enum;
};
10.10.2.5. Bitmask Types

Bitmask types are defined using the <bitmask> tag. Attribute name and at least on <bit_value> child element are mandatory. Optionally, bit_bound attribute might be set to specify the bitmask bound (by default 32 bits). Bitflag elements are defined using the <bit_value> tag with mandatory attribute name. Optionally, position attribute might be defined to set the bitflag position within the bitmask. Please, refer to Bitmask Types for more information on bitmask types.

<bitmask name="MyBitMask" bit_bound="8">
    <bit_value name="flag0" position="0"/>
    <bit_value name="flag1"/>
    <bit_value name="flag2"/>
    <bit_value name="flag5" position="5"/>
</bitmask>

<struct name="BitmaskStruct">
    <member name="my_bitmask" type="nonBasic" nonBasicTypeName="MyBitMask"/>
</struct>
@bit_bound(8)
bitmask MyBitMask
{
    @position(0) flag0,
    flag1,
    flag2,
    @position(5) flag5
};

struct BitmaskStruct
{
    MyBitMask my_bitmask;
};
10.10.2.6. Alias Types

Alias types are defined using the <typedef> tag. Attributes name and type are mandatory. Depending on the aliased type, some other mandatory and/or optional attributes might be necessary or available. Non-primitive types must define the type attribute as nonBasic and include the nonBasicTypeName attribute with the name of the aliased type. Please, refer to Alias Types for more information on alias types.

<typedef name="MyAliasedEnum" type="nonBasic" nonBasicTypeName="MyEnum"/>
<!-- XSD does not allow to set bounds to aliased strings -->
<typedef name="MyAliasedBoundedString" type="string"/>
<typedef name="MyRecursiveAlias" type="nonBasic" nonBasicTypeName="MyAliasedEnum"/>

<struct name="AliasStruct">
    <member name="my_aliased_enum" type="nonBasic" nonBasicTypeName="MyAliasedEnum"/>
    <member name="my_aliased_bounded_string" type="nonBasic" nonBasicTypeName="MyAliasedBoundedString"/>
    <member name="my_recursive_alias" type="nonBasic" nonBasicTypeName="MyRecursiveAlias"/>
</struct>
typedef MyEnum MyAliasedEnum;
typedef string<100> MyAliasedBoundedString;
typedef MyAliasedEnum MyRecursiveAlias;

struct AliasStruct
{
    MyAliasedEnum my_aliased_enum;
    MyAliasedBoundedString my_aliased_bounded_string;
    MyRecursiveAlias my_recursive_alias;
};
10.10.2.7. Sequence Types

Sequence types should be defined as members of an aggregated type (Structure Types or Union Types). Sequence types are defined with mandatory attributes type set to the collection’s element type, and sequenceMaxLength used to set the maximum collection’s length. Unbounded sequences should set sequenceMaxLength attribute to -1. Please, refer to Sequence types for more information on sequence types.

<struct name="SequenceStruct">
    <member name="bitmask_sequence" type="nonBasic" nonBasicTypeName="MyBitMask" sequenceMaxLength="-1"/>
    <member name="short_sequence" sequenceMaxLength="5" type="int16"/>
</struct>
struct SequenceStruct
{
    sequence<MyBitMask> bitmask_sequence;
    sequence<short, 5> short_sequence;
};
10.10.2.8. Array Types

Array types should be defined as members of an aggregated type (Structure Types or Union Types). Array types are defined with mandatory attributes type set to the collection’s element type, and arrayDimensions used to set the collection’s dimensions. The format of arrayDimensions attribute value is the size of each dimension separated by commas. Please, refer to Array types for more information on array types.

<struct name="ArrayStruct">
    <member name="long_array" type="int32" arrayDimensions="2,3,4"/>
</struct>
struct ArrayStruct
{
    long long_array[2][3][4];
};
10.10.2.9. Map Types

Map types should be defined as members of an aggregated type (Structure Types or Union Types). Map types are defined with mandatory attributes type set to the map’s value type, key_type set to the map’s key type, and mapMaxLength used to set the maximum map’s number of key-value pairs. Unbounded maps should set mapMaxLength attribute to -1. Please, refer to Map Types for more information on map types.

<struct name="MapStruct">
    <member name="string_alias_unbounded_map" type="nonBasic" nonBasicTypeName="MyAliasedBoundedString" key_type="string" mapMaxLength="-1"/>
    <member name="short_long_map" type="int32" key_type="int16" mapMaxLength="2"/>
</struct>
struct MapStruct
{
    map<string, MyAliasedBoundedString> string_alias_unbounded_map;
    map<short, long, 2> short_long_map;
};
10.10.2.10. Structure Types

Structure types are defined using the <struct> tag with mandatory attribute name. Structure inheritance may be configured setting optional attribute baseType. XML Structure Types require at least one member defined.

Note

IDL specification introduced in version 4.1 the possibility of void content structures. Empty structures are not supported in XML Types profiles yet.

Structure members are defined using the <member> tag with mandatory attributes name and type. Depending on the member type, some other mandatory and/or optional attributes might be necessary or available. Non-primitive types must define the type attribute as nonBasic and include the nonBasicTypeName attribute with the name of the member type.

Note

Currently, XML Types profiles does not support setting the member ID or marking a member as key.

Please, refer to Structure Types for more information on structure types.

<struct name="InnerStruct">
    <!-- XML does not support setting Member ID -->
    <member name="first" type="int32"/>
</struct>

<!-- TODO(XTypes: Fix inheritance loading from XML profile) Fast DDS#4626 -->
<!-- <struct name="ParentStruct">
    <member name="first" type="float32"/>
    <member name="second" type="int64"/>
</struct>

<struct name="ComplexStruct" baseType="ParentStruct">
    <member name="complex_member" type="nonBasic" nonBasicTypeName="InnerStruct"/>
</struct> -->
struct InnerStruct
{
    @id(0x10) long first;
};

struct ParentStruct
{
    float first;
    long long second;
};

struct ComplexStruct : ParentStruct
{
    InnerStruct complex_member;
};
10.10.2.11. Union Types

Union types are defined using the <union> tag with mandatory attribute name. A mandatory discriminator child must be defined using <discriminator> tag. Discriminator element requires <type> as mandatory attribute.

Union types also require at least one case child defined using the <case> tag. Each case child requires at least one label child using the <caseDiscriminator> tag. value attribute is mandatory and defines the label value. Several labels might be defined using several <caseDiscriminator> elements. Each case child must have exclusively one union member defined.

Union members are defined using the <member> tag with mandatory attributes name and type. Depending on the member type, some other mandatory and/or optional attributes might be necessary or available. Non-primitive types must define the type attribute as nonBasic and include the nonBasicTypeName attribute with the name of the member type. At least one union member must be defined for the union type to be consistent.

Note

Currently, XML Types profiles does not support setting the member ID or marking a member as key.

Please, refer to Union Types for more information on the union types.

<union name="InnerUnion">
    <discriminator type="int16"/>
    <case>
        <caseDiscriminator value="0"/>
        <member name="first" type="nonBasic" nonBasicTypeName="PrimitivesStruct"/>
    </case>
    <case>
        <caseDiscriminator value="1"/>
        <caseDiscriminator value="default"/>
        <member name="second" type="int64"/>
    </case>
</union>
<union name="ComplexUnion">
    <discriminator type="int32"/>
    <case>
        <caseDiscriminator value="0"/>
        <caseDiscriminator value="1"/>
        <member name="third" type="int32"/>
    </case>
    <case>
        <caseDiscriminator value="default"/>
        <member name="fourth" type="nonBasic" nonBasicTypeName="InnerUnion"/>
    </case>
</union>
union InnerUnion switch (short)
{
    case 0:
        @id(0x10) PrimitivesStruct first;
    case 1:
    default:
        long long second;
};

union ComplexUnion switch (long)
{
    case 0:
    case 1:
        long third;
    default:
        InnerUnion fourth;
};
10.10.2.12. Bitset Types

Bitset types are defined using the <bitset> tag with mandatory attribute name. Bitset inheritance may be configured setting optional attribute baseType. At least one bitfield child must be defined using bitfield tag.

Bitfield elements require mandatory attribute bit_bound with the number of bits managed by the bitfield (maximum 64 bits). Optionally, attributes name and type might be defined. An anonymous bitfield (attribute name not set) is not accessible and serves as padding between named bitfields. The type attribute can ease bitfield management explicitly setting an integer type that handles the bitfield.

Please, refer to Bitset Types for more information about the bitset types.

<bitset name="ParentBitset">
    <bitfield name="a" bit_bound="3"/>
    <bitfield name="b" bit_bound="1"/>
    <bitfield bit_bound="4"/>
    <bitfield name="c" bit_bound="10"/>
    <bitfield name="d" bit_bound="12" type="int16"/>
</bitset>

<!-- TODO(XTypes: Fix inheritance loading from XML profile) Fast DDS#4626 -->
<!--<bitset name="ChildBitSet" baseType="ParentBitSet">
    <bitfield name="e" bit_bound="1"/>
    <bitfield name="f" bit_bound="20" type="uint32"/>
</bitset>

<struct name="BitsetStruct">
    <member name="my_bitset" type="nonBasic" nonBasicTypeName="ChildBitSet"/>
</struct>-->
bitset ParentBitSet
{
    bitfield<3> a;
    bitfield<1> b;
    bitfield<4>;
    bitfield<10> c;
    bitfield<12, short> d;
};

bitset ChildBitSet : ParentBitSet
{
    bitfield<1> e;
    bitfield<20, unsigned long> f;
};

struct BitsetStruct
{
   ChildBitSet my_bitset;
};

10.10.3. Loading XML Types profile in Fast DDS application

Fast DDS application can use types defined in XML configuration files once those files have been loaded into the DomainParticipantFactory using load_XML_profiles_file(). Types might be retrieved using DomainParticipantFactory::get_dynamic_type_builder_from_xml_by_name(). After getting the DynamicType, objects of DynamicPubSubType class might be instantiated and used to write/read data.

// Create a DomainParticipant
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Load the XML File
if (RETCODE_OK ==
        DomainParticipantFactory::get_instance()->load_XML_profiles_file("my_profiles.xml"))
{
    // Retrieve instance of the desired type
    DynamicTypeBuilder::_ref_type my_struct_type;
    if (RETCODE_OK !=
            DomainParticipantFactory::get_instance()->get_dynamic_type_builder_from_xml_by_name(
                "MyStruct", my_struct_type))
    {
        // Error
        return;
    }

    // Register MyStruct type
    TypeSupport my_struct_type_support(new DynamicPubSubType(my_struct_type->build()));
    my_struct_type_support.register_type(participant, nullptr);
}
else
{
    std::cout << "Cannot open XML file \"types.xml\". "
              << "Please, set the correct path to the XML file"
              << std::endl;
}

10.11. Common

The preceding XML profiles define some XML elements that are common to several profiles. This section aims to explain these common elements.

10.11.1. LocatorListType

It represents a list of Locator_t. LocatorListType is used inside other configuration parameter labels that expect a list of locators, for example, in <defaultUnicastLocatorList>. Therefore, LocatorListType is defined as a set of <locator> elements. The <locator> element has a single child element that defines the transport protocol for which the locator is defined. These are: <udpv4>, <tcpv4>, <udpv6>, and <tcpv6>. The table presented below outlines each possible Locator’s field.

Note

SHM transport locators cannot be configured as they are automatically handled by SHM.

Name

Description

Values

Default

<port>

RTPS port number of the locator.
Physical port in UDP, logical port in TCP.

uint16_t

0

<physical_port>

TCP’s physical port.

uint16_t

0

<address>

IP address of the locator.

string (IPv4/IPv6 format
or DNS name)

Empty

<unique_lan_id>

The LAN ID uniquely identifies the LAN the
locator belongs to (TCPv4 only).

string (16 bytes)

Empty

<wan_address>

WAN IPv4 address (TCPv4 only).

string (IPv4 format)

0.0.0.0

Example

The following example shows the implementation of one locator of each transport protocol in <defaultUnicastLocatorList>.

<defaultUnicastLocatorList>
    <locator>
        <udpv4>
            <!-- Access as physical, typical UDP usage -->
            <port>7400</port>
            <address>192.168.1.41</address>
        </udpv4>
        <udpv4>
            <!-- Access as physical, typical UDP usage -->
            <port>7600</port>
            <address>localhost</address>
        </udpv4>
    </locator>
    <locator>
        <tcpv4>
            <!-- Both physical and logical (port), useful in TCP transports -->
            <physical_port>5100</physical_port>
            <port>7400</port>
            <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
            <wan_address>80.80.99.45</wan_address>
            <address>192.168.1.55</address>
        </tcpv4>
    </locator>
    <locator>
        <udpv6>
            <port>8844</port>
            <address>::1</address>
        </udpv6>
        <udpv6>
            <port>8888</port>
            <address>localhost</address>
        </udpv6>
    </locator>
    <locator>
        <tcpv6>
            <!-- Both physical and logical (port), useful in TCP transports -->
            <physical_port>5100</physical_port>
            <port>7400</port>
            <address>fe80::55e3:290:165:5af8</address>
        </tcpv6>
    </locator>
</defaultUnicastLocatorList>

10.11.2. ExternalLocatorListType

It represents a list of external locator entries. Each entry can be a <udpv4> or a <udpv6> tag. These tags can be configured with the following attributes:

Name

Description

Values

Default

externality

Number of hops from the participant’s host to the
LAN represented by the external locator.
Valid values: from 1 to 255.

uint8_t

1

cost

Communication cost relative to other locators on
the same externality level.
Valid values: from 0 to 255.

uint8_t

0

mask

Number of significant bits on the LAN represented
by the external locator.
Valid values: from 1 to 31 (UDPv4) or 127 (UDPv6)

uint8_t

24

They should contain the following tags:

Name

Description

Values

<port>

UDP port number of the locator.
The UDP port number should be valid.

uint16_t

<address>

IP address of the locator.

string (IPv4/IPv6 format
or DNS name)

Example

The following example shows the implementation of one locator of each transport protocol in <default_external_unicast_locators>.

<default_external_unicast_locators>
    <udpv4 externality="1" cost="0" mask="24">
        <address>100.100.100.10</address>
        <port>23456</port>
    </udpv4>
    <udpv6 externality="2" cost="0" mask="48">
        <address>::1</address>
        <port>1234</port>
    </udpv6>
</default_external_unicast_locators>

10.11.3. PropertiesPolicyType

PropertiesPolicyType defines the <propertiesPolicy> element. It allows the user to define a set of generic properties inside a <properties> element. It is useful at defining extended or custom configuration parameters.

Name

Description

Values

Default

<name>

Name to identify the property.

string

<value>

Property’s value.

string

<propagate>

Indicates if it is going to be serialized along with the
object it belongs to.

bool

false

Example

<propertiesPolicy>
    <properties>
        <property>
            <name>Property1Name</name>
            <value>Property1Value</value>
            <propagate>false</propagate>
        </property>
        <property>
            <name>Property2Name</name>
            <value>Property2Value</value>
            <propagate>true</propagate>
        </property>
    </properties>
</propertiesPolicy>

10.11.4. DurationType

DurationType expresses a period of time and it is commonly used inside other XML elements, such as in <leaseAnnouncement> or <leaseDuration>. A DurationType is defined by at least one mandatory element of two possible ones: <sec> plus <nanosec>. An infinite value can be specified by using the values DURATION_INFINITY, DURATION_INFINITE_SEC and DURATION_INFINITE_NSEC.

Name

Description

Values

Default

<sec>

Number of seconds.

int32_t

0

<nanosec>

Number of nanoseconds.

uint32_t

0

Example

<discovery_config>
    <leaseDuration>
        <sec>DURATION_INFINITY</sec>
    </leaseDuration>
    <leaseAnnouncement>
        <sec>1</sec>
        <nanosec>856000</nanosec>
    </leaseAnnouncement>
</discovery_config>

10.11.5. TopicType

This XML element allows the configuration of the specific HistoryQosPolicy and ResourceLimitsQosPolicy QoS of the Datawriters and DataReaders in which this element is defined inside of. Also, it sets the TopicQos configuration with the policies detailed.

Name

Description

Values

<historyQos>

It controls the behavior of Fast DDS
when the value of an instance changes
before it is finally communicated to
some of its existing DataReaders.

HistoryQoS

<resourceLimitsQos>

It controls the resources that Fast DDS
can use in order to meet the
requirements imposed by the application
and other QoS settings.

ResourceLimitsQos

Example

<data_writer profile_name="dataWriter_topic_example">
    <topic>
        <historyQos>
            <kind>KEEP_LAST</kind>
            <depth>20</depth>
        </historyQos>
        <resourceLimitsQos>
            <max_samples>5</max_samples>
            <max_instances>2</max_instances>
            <max_samples_per_instance>1</max_samples_per_instance>
            <allocated_samples>20</allocated_samples>
            <extra_samples>10</extra_samples>
        </resourceLimitsQos>
    </topic>
</data_writer>
10.11.5.1. HistoryQoS

It controls the behavior of Fast DDS when the value of an instance changes before it is finally communicated to some of its existing DataReaders. Please refer to HistoryQosPolicyKind for further information on HistoryQoS.

Name

Description

Values

Default

<kind>

Fast DDS will only attempt to keep the latest values of the instance
and discard the older ones.

KEEP_LAST

KEEP_LAST

Fast DDS will attempt to maintain and deliver all the values of the instance
to existing DataReaders.

KEEP_ALL

<depth>

It must be consistent with the ResourceLimitsQos <max_samples_per_instance>
element value. It must be verified that:
<depth> <= <max_samples_per_instance>.

uint32_t

1

10.11.5.2. ResourceLimitsQos

It controls the resources that Fast DDS can use in order to meet the requirements imposed by the application and other QoS settings. Please refer to ResourceLimitsQosPolicy for further information on ResourceLimitsQos.

Name

Description

Values

Default

<max_samples>

It must verify that: <max_samples> >= <max_samples_per_instance>.

int32_t

5000

<max_instances>

It defines the maximum number of instances.

int32_t

10

<max_samples_per_instance>

It must verify that: HistoryQos <depth> <= <max_samples_per_instance>.

int32_t

400

<allocated_samples>

It controls the maximum number of samples to be stored.

int32_t

100

<extra_samples>

The number of extra samples to allocate on the pool.

int32_t

1

10.11.6. ThreadSettings

It controls some OS settings for the Fast DDS created threads. Please refer to ThreadSettings for further information on ResourceLimitsQos.

Name

Description

Values

Default

scheduling_policy

Configures the scheduling policy used for the thread.

int32_t

-1

priority

Configures the thread’s priority.

int32_t

-2^31

affinity

On some systems (Windows, Linux), this is a bit mask for setting
the threads affinity to each core individually. On MacOS, this
sets the affinity tag for the thread, and the OS tries to share
the L2 cache between threads with the same affinity.

uint32_t

0

stack_size

Configures the thread’s stack size in bytes.

int32_t

-1

10.11.7. BuiltinTransports

It controls the builtin transports that will be used during the initialization of the DomainParticipant. Please refer to Managing the Builtin Transports for further information on builtin transports.

This type must follow this configuration:

Name

Description

Values

Default

<builtinTransport>

Defines the builtin transport mode.

NONE
DEFAULT
DEFAULTv6
SHM
UDPv4
UDPv6
LARGE_DATA

DEFAULT

The <builtinTransport> tag can be configured with the following attributes:

Name

Description

Values

Default

max_msg_size

Maximum message size that will be specified in the transport layer.
Valid values: from 1 to (2^32)-1.

uint32_t

65500

sockets_size

Size of the send and receive socket buffers. Valid values: from 0 to (2^32)-1.

uint32_t

OS default

non_blocking

Whether to use non-blocking send calls or not. Valid values: true or false.

bool

false

tcp_negotiation_timeout

Timeout duration for logical port negotiation. Valid values: from 1 to (2^32)-1.
Only valid for LARGE_DATA mode.

uint32_t

0

10.11.8. QoS

The Quality of Service (QoS) is used to specify the behavior of the Service, allowing the user to define how each Entity will behave. Please refer to the Policy section for more information on QoS.

Name

Description

Values

<data_sharing>

See DataSharingQosPolicy

Data-Sharing

<deadline>

See DeadlineQosPolicy.

Deadline

<disable_heartbeat_piggyback>

See DisableHeartbeatPiggyback.

DisableHeartbeatPiggyback

<disablePositiveAcks>

See DisablePositiveACKsQosPolicy.

DisablePositiveAcks

<durability>

See DurabilityQosPolicy.

Durability

<entity_factory>

See EntityFactoryQosPolicy.

Entity Factory

<groupData>

See GroupDataQosPolicy.

GroupData

<latencyBudget>

See LatencyBudgetQosPolicy.

LatencyBudget

<lifespan>

See LifespanQosPolicy.

Lifespan

<liveliness>

See LivelinessQosPolicy.

Liveliness

<ownership>

See OwnershipQosPolicy.

Ownership

<ownershipStrength>

See OwnershipStrengthQosPolicy.

Ownership Strength

<partition>

See PartitionQosPolicy.

Partition

<publishMode>

See PublishModeQosPolicy.

PublishMode

<reliability>

See ReliabilityQosPolicy.

ReliabilityQosPolicy

<topicData>

See TopicDataQosPolicy.

TopicData

<userData>

See UserDataQosPolicy.

UserData

Example

<data_writer profile_name="pub_topic_qos">
<qos> <!-- writerQosPoliciesType -->
    <data_sharing>
        <kind>AUTOMATIC</kind>
        <shared_dir>/home</shared_dir>
        <max_domains>10</max_domains>
        <domain_ids>
            <domainId>0</domainId>
            <domainId>11</domainId>
        </domain_ids>
    </data_sharing>

    <deadline>
        <period>
            <sec>1</sec>
        </period>
    </deadline>

    <!-- DataWriter specific QoS -->
    <disable_heartbeat_piggyback>true</disable_heartbeat_piggyback>

    <disablePositiveAcks>
        <enabled>true</enabled>
        <duration>
            <sec>1</sec>
        </duration>
    </disablePositiveAcks>

    <durability>
        <kind>VOLATILE</kind>
    </durability>

    <groupData>
        <value>1.a.2</value>
    </groupData>

    <!-- QoS policy pending implementation -->
    <latencyBudget>
        <duration>
            <sec>1</sec>
        </duration>
    </latencyBudget>

    <lifespan>
        <duration>
            <sec>1</sec>
        </duration>
    </lifespan>

    <liveliness>
        <kind>AUTOMATIC</kind>

        <lease_duration>
            <sec>1</sec>
        </lease_duration>

        <announcement_period>
            <sec>1</sec>
        </announcement_period>
    </liveliness>

    <ownership>
        <kind>EXCLUSIVE</kind>
    </ownership>

    <!-- DataWriter specific QoS -->
    <ownershipStrength>
        <value>50</value>
    </ownershipStrength>

    <partition>
        <names>
            <name>part1</name>
            <name>part2</name>
        </names>
    </partition>

    <!-- DataWriter specific QoS -->
    <publishMode>
        <kind>ASYNCHRONOUS</kind>
    </publishMode>

    <reliability>
        <kind>BEST_EFFORT</kind>
        <max_blocking_time>
            <sec>1</sec>
        </max_blocking_time>
    </reliability>

    <topicData>
        <value>2.b.1</value>
    </topicData>

    <userData>
        <value>3.c.0</value>
    </userData>
</qos>
10.11.8.1. Data-Sharing

Name

Description

Values

Default

<kind>

See DataSharingKind

AUTOMATIC
ON
OFF

AUTOMATIC

<shared_dir>

Directory used for the memory-mapped files.

string

Empty

<max_domains>

Maximum number of Data-Sharing domain IDs
in the local or remote endpoints.

uint32_t

0 (unlimited)

<domain_ids>

List of Data-Sharing domain IDs configured
for the current endpoint.

<domainId>

Empty list

Name

Description

Values

<domainId>

Domain ID to be used by the endpoint for Data-Sharing.

uint32_t

10.11.8.2. Deadline

Name

Description

Values

Default

<period>

See DeadlineQosPolicy.

DurationType

c_TimeInfinite

10.11.8.3. DisableHeartbeatPiggyback

Name

Description

Values

Default

<disable_heartbeat_piggyback>

See DisableHeartbeatPiggyback.

bool

false

Important

This configuration is only available for DataWriter QoS profile configuration.

10.11.8.4. DisablePositiveAcks

Name

Description

Values

Default

<enabled>

See DisablePositiveACKsQosPolicy.

bool

false

<duration>

See DisablePositiveACKsQosPolicy.

DurationType

c_TimeInfinite

10.11.8.5. Durability

Name

Description

Values

Default

<kind>

See DurabilityQosPolicyKind.

VOLATILE
TRANSIENT_LOCAL
TRANSIENT
PERSISTENT

DataReaders: VOLATILE
DataWriters: TRANSIENT_LOCAL

10.11.8.6. Entity Factory

Name

Description

Values

Default

<autoenable_created_entities>

See EntityFactoryQosPolicy.

bool

true

10.11.8.7. GroupData

Name

Description

Values

Default

<value>

See GroupDataQosPolicy.

string (std::vector<octet>)

Empty

10.11.8.8. LatencyBudget

Name

Description

Values

Default

<duration>

See LatencyBudgetQosPolicy.

DurationType

0

10.11.8.9. Lifespan

Name

Description

Values

Default

<duration>

See LifespanQosPolicy.

DurationType

c_TimeInfinite

10.11.8.10. Liveliness
10.11.8.11. Ownership

Name

Description

Values

Default

<kind>

See OwnershipQosPolicyKind.

SHARED
EXCLUSIVE

SHARED

10.11.8.12. Ownership Strength

Name

Description

Values

Default

<value>

See OwnershipStrengthQosPolicy.

uint32_t

0

Important

This configuration is only available for DataWriter QoS profile configuration.

10.11.8.13. Partition

Name

Description

Values

<names>

It comprises a set of <name> elements containing the name of each partition.
See PartitionQosPolicy.

<name>

10.11.8.14. PublishMode

Name

Description

Values

Default

<kind>

See PublishModeQosPolicy.

ASYNCHRONOUS

ASYNCHRONOUS

SYNCHRONOUS

<flow_controller_name>

FlowControllersQos name.

<string>

Empty

Important

This configuration is only available for DataWriter QoS profile configuration.

10.11.8.15. ReliabilityQosPolicy

Name

Description

Values

Default

<kind>

See ReliabilityQosPolicyKind.

BEST_EFFORT

DataReaders: BEST_EFFORT
DataWriters: RELIABLE

RELIABLE

<max_blocking_time>

See ReliabilityQosPolicy.

DurationType

100 ms

10.11.8.16. TopicData

Name

Description

Values

Default

<value>

See TopicDataQosPolicy.

string (std::vector<octet>)

Empty

10.11.8.17. UserData

Name

Description

Values

Default

<value>

See UserDataQosPolicy.

string (std::vector<octet>)

Empty

10.11.9. HistoryMemoryPolicy

Indicates the way the memory is managed in terms of dealing with the CacheChanges of the RTPSEndpointQos.

Name

Description

Values

Default

<historyMemoryPolicy>

Four different options as described
in MemoryManagementPolicy.

PREALLOCATED
PREALLOCATED_WITH_REALLOC
DYNAMIC
DYNAMIC_REUSABLE

PREALLOCATED

Example

<data_writer profile_name="data_writer_historyMemoryPolicy">
    <!-- ...  -->
    <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
</data_writer>

<data_reader profile_name="data_reader_historyMemoryPolicy">
    <!-- ...  -->
    <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
</data_reader>

10.11.10. Allocation Configuration

The <allocation> element allows to control the allocation behavior of internal collections for which the number of elements depends on the number of entities in the system. For instance, there are collections inside a DataWriter which depend on the number of DataReaders matching with it. Please refer to ParticipantResourceLimitsQos for a detailed documentation on DomainParticipant allocation, and to Tuning allocations for detailed information on how to tune allocation related parameters.

Name

Description

Values

Default

<initial>

Number of elements for which space is initially allocated.

uint32_t

0

<maximum>

Maximum number of elements for which space will be allocated.

uint32_t

0 (Means no limit)

<increment>

Number of new elements that will be allocated when more space is
necessary.

uint32_t

1

10.11.11. Flow Controller Descriptors

This <flow_controller_descriptor_list> element configures the list of flow controllers of a participant, so they can later be used on its DataWriters. Please refer to FlowControllersQos for a detailed documentation.

Data Member Name

Type

Default Value

<name>

string

Empty

<scheduler>

FlowControllerSchedulerPolicy

FIFO

<max_bytes_per_period>

int32_t

0 (i.e. infinite)

<period_ms>

uint64_t

100

<sender_thread>

ThreadSettings

10.12. Example

In this section, there is a full XML example with all possible configuration.

Warning

This example can be used as a quick reference, but it may not be correct due to incompatibility or exclusive properties. Do not take it as a working example.

   1<?xml version="1.0" encoding="UTF-8" ?>
   2<dds xmlns="http://www.eprosima.com">
   3    <profiles>
   4        <transport_descriptors>
   5            <!-- TCP sample transport descriptor -->
   6            <transport_descriptor>
   7                <transport_id>ExampleTransportId1</transport_id>
   8                <type>TCPv4</type>
   9                <sendBufferSize>8192</sendBufferSize>
  10                <receiveBufferSize>8192</receiveBufferSize>
  11                <maxMessageSize>16384</maxMessageSize>
  12                <maxInitialPeersRange>100</maxInitialPeersRange>
  13                <netmask_filter>AUTO</netmask_filter>
  14                <interfaces>
  15                    <allowlist>
  16                        <interface name="wlp59s0" netmask_filter="ON"/>
  17                    </allowlist>
  18                    <blocklist>
  19                        <interface name="127.0.0.1"/>
  20                        <interface name="docker0"/>
  21                    </blocklist>
  22                </interfaces>
  23                <interfaceWhiteList>
  24                    <address>192.168.1.41</address>
  25                    <interface>lo</interface>
  26                </interfaceWhiteList>
  27                <wan_addr>80.80.55.44</wan_addr>
  28                <keep_alive_frequency_ms>5000</keep_alive_frequency_ms>
  29                <keep_alive_timeout_ms>25000</keep_alive_timeout_ms>
  30                <max_logical_port>200</max_logical_port>
  31                <logical_port_range>20</logical_port_range>
  32                <logical_port_increment>2</logical_port_increment>
  33                <listening_ports>
  34                    <port>5100</port>
  35                    <port>5200</port>
  36                </listening_ports>
  37                <tls>
  38                    <password>Password</password>
  39                    <private_key_file>Key_file.pem</private_key_file>
  40                    <rsa_private_key_file>RSA_file.pem</rsa_private_key_file>
  41                    <cert_chain_file>Chain.pem</cert_chain_file>
  42                    <tmp_dh_file>DH.pem</tmp_dh_file>
  43                    <verify_file>verify.pem</verify_file>
  44                    <verify_mode>
  45                        <verify>VERIFY_PEER</verify>
  46                    </verify_mode>
  47                    <options>
  48                        <option>NO_TLSV1</option>
  49                        <option>NO_TLSV1_1</option>
  50                    </options>
  51                    <verify_paths>
  52                        <verify_path>Path1</verify_path>
  53                        <verify_path>Path2</verify_path>
  54                        <verify_path>Path3</verify_path>
  55                    </verify_paths>
  56                    <verify_depth>55</verify_depth>
  57                    <default_verify_path>true</default_verify_path>
  58                    <handshake_role>SERVER</handshake_role>
  59                    <server_name>my_server.com</server_name>
  60                </tls>
  61                <calculate_crc>false</calculate_crc>
  62                <check_crc>false</check_crc>
  63                <enable_tcp_nodelay>false</enable_tcp_nodelay>
  64                <default_reception_threads>
  65                    <scheduling_policy>-1</scheduling_policy>
  66                    <priority>0</priority>
  67                    <affinity>0</affinity>
  68                    <stack_size>-1</stack_size>
  69                </default_reception_threads>
  70                <reception_threads>
  71                    <reception_thread port="12345">
  72                        <scheduling_policy>-1</scheduling_policy>
  73                        <priority>0</priority>
  74                        <affinity>0</affinity>
  75                        <stack_size>-1</stack_size>
  76                    </reception_thread>
  77                </reception_threads>
  78            </transport_descriptor>
  79            <!-- UDP sample transport descriptor. Several options are common with TCP -->
  80            <transport_descriptor>
  81                <transport_id>ExampleTransportId2</transport_id>
  82                <type>UDPv6</type>
  83                <TTL>250</TTL>
  84                <non_blocking_send>false</non_blocking_send>
  85                <output_port>5101</output_port>
  86                <default_reception_threads>
  87                    <scheduling_policy>-1</scheduling_policy>
  88                    <priority>0</priority>
  89                    <affinity>0</affinity>
  90                    <stack_size>-1</stack_size>
  91                </default_reception_threads>
  92                <reception_threads>
  93                    <reception_thread port="12345">
  94                        <scheduling_policy>-1</scheduling_policy>
  95                        <priority>0</priority>
  96                        <affinity>0</affinity>
  97                        <stack_size>-1</stack_size>
  98                    </reception_thread>
  99                </reception_threads>
 100            </transport_descriptor>
 101            <!-- SHM sample transport descriptor -->
 102            <transport_descriptor>
 103                <transport_id>SHM_SAMPLE_DESCRIPTOR</transport_id>
 104                <type>SHM</type> <!-- REQUIRED -->
 105                <maxMessageSize>524288</maxMessageSize> <!-- OPTIONAL uint32 valid of all transports-->
 106                <segment_size>1048576</segment_size> <!-- OPTIONAL uint32 SHM only-->
 107                <port_queue_capacity>1024</port_queue_capacity> <!-- OPTIONAL uint32 SHM only-->
 108                <healthy_check_timeout_ms>250</healthy_check_timeout_ms> <!-- OPTIONAL uint32 SHM only-->
 109                <rtps_dump_file>test_file.dump</rtps_dump_file> <!-- OPTIONAL string SHM only-->
 110                <default_reception_threads> <!-- OPTIONAL -->
 111                    <scheduling_policy>-1</scheduling_policy>
 112                    <priority>0</priority>
 113                    <affinity>0</affinity>
 114                    <stack_size>-1</stack_size>
 115                </default_reception_threads>
 116                <reception_threads> <!-- OPTIONAL -->
 117                    <reception_thread port="12345">
 118                        <scheduling_policy>-1</scheduling_policy>
 119                        <priority>0</priority>
 120                        <affinity>0</affinity>
 121                        <stack_size>-1</stack_size>
 122                    </reception_thread>
 123                </reception_threads>
 124                <dump_thread>
 125                    <scheduling_policy>-1</scheduling_policy>
 126                    <priority>0</priority>
 127                    <affinity>0</affinity>
 128                    <stack_size>-1</stack_size>
 129                </dump_thread>
 130            </transport_descriptor>
 131        </transport_descriptors>
 132
 133        <domainparticipant_factory profile_name="domainparticipant_factory_profile_name">
 134            <qos>
 135                <entity_factory>
 136                    <autoenable_created_entities>true</autoenable_created_entities>
 137                </entity_factory>
 138                <shm_watchdog_thread>
 139                    <scheduling_policy>-1</scheduling_policy>
 140                    <priority>0</priority>
 141                    <affinity>0</affinity>
 142                    <stack_size>-1</stack_size>
 143                </shm_watchdog_thread>
 144                <file_watch_threads>
 145                    <scheduling_policy>-1</scheduling_policy>
 146                    <priority>0</priority>
 147                    <affinity>0</affinity>
 148                    <stack_size>-1</stack_size>
 149                </file_watch_threads>
 150            </qos>
 151        </domainparticipant_factory>
 152
 153        <participant profile_name="participant_profile_example">
 154            <domainId>4</domainId>
 155            <rtps>
 156                <name>Participant Name</name> <!-- String -->
 157
 158                <defaultUnicastLocatorList>
 159                    <locator>
 160                        <udpv4>
 161                            <!-- Access as physical, like UDP -->
 162                            <port>7400</port>
 163                            <address>localhost</address>
 164                        </udpv4>
 165                    </locator>
 166                    <locator>
 167                        <tcpv4>
 168                            <!-- Both physical and logical (port), like TCP -->
 169                            <physical_port>5100</physical_port>
 170                            <port>7400</port>
 171                            <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 172                            <wan_address>80.80.99.45</wan_address>
 173                            <address>192.168.1.55</address>
 174                        </tcpv4>
 175                    </locator>
 176                    <locator>
 177                        <udpv6>
 178                            <port>8844</port>
 179                            <address>::1</address>
 180                        </udpv6>
 181                    </locator>
 182                </defaultUnicastLocatorList>
 183
 184                <defaultMulticastLocatorList>
 185                    <locator>
 186                        <udpv4>
 187                            <!-- Access as physical, like UDP -->
 188                            <port>7400</port>
 189                            <address>192.168.1.41</address>
 190                        </udpv4>
 191                    </locator>
 192                    <locator>
 193                        <tcpv4>
 194                            <!-- Both physical and logical (port), like TCP -->
 195                            <physical_port>5100</physical_port>
 196                            <port>7400</port>
 197                            <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 198                            <wan_address>80.80.99.45</wan_address>
 199                            <address>192.168.1.55</address>
 200                        </tcpv4>
 201                    </locator>
 202                    <locator>
 203                        <udpv6>
 204                            <port>8844</port>
 205                            <address>::1</address>
 206                        </udpv6>
 207                    </locator>
 208                </defaultMulticastLocatorList>
 209
 210                <default_external_unicast_locators>
 211                    <!-- EXTERNAL_LOCATOR_LIST -->
 212                    <udpv4 externality="1" cost="0" mask="24">
 213                        <address>100.100.100.10</address>
 214                        <port>23456</port>
 215                    </udpv4>
 216                    <udpv6 externality="1" cost="1" mask="48">
 217                        <address>::1</address>
 218                        <port>1234</port>
 219                    </udpv6>
 220                </default_external_unicast_locators>
 221
 222                <ignore_non_matching_locators>true</ignore_non_matching_locators>
 223                <sendSocketBufferSize>8192</sendSocketBufferSize>
 224                <listenSocketBufferSize>8192</listenSocketBufferSize>
 225                <netmask_filter>AUTO</netmask_filter>
 226
 227                <builtin>
 228                    <discovery_config>
 229                        <discoveryProtocol>NONE</discoveryProtocol>
 230                        <discoveryServersList>
 231                            <locator>
 232                                <udpv4>
 233                                    <address>192.168.10.57</address>
 234                                    <port>56542</port>
 235                                </udpv4>
 236                            </locator>
 237                            <locator>
 238                                <udpv4>
 239                                    <address>192.168.10.58</address>
 240                                    <port>24565</port>
 241                                </udpv4>
 242                            </locator>
 243                            <locator>
 244                                <udpv4>
 245                                    <address>192.168.10.59</address>
 246                                    <port>56543</port>
 247                                </udpv4>
 248                            </locator>
 249                            <locator>
 250                                <udpv4>
 251                                    <address>192.168.10.60</address>
 252                                    <port>34565</port>
 253                                </udpv4>
 254                            </locator>
 255                        </discoveryServersList>
 256                        <ignoreParticipantFlags>FILTER_DIFFERENT_PROCESS|FILTER_SAME_PROCESS</ignoreParticipantFlags>
 257                        <EDP>SIMPLE</EDP>
 258                        <simpleEDP>
 259                            <PUBWRITER_SUBREADER>true</PUBWRITER_SUBREADER>
 260                            <PUBREADER_SUBWRITER>true</PUBREADER_SUBWRITER>
 261                        </simpleEDP>
 262                        <leaseDuration>
 263                            <sec>DURATION_INFINITY</sec>
 264                        </leaseDuration>
 265                        <leaseAnnouncement>
 266                            <sec>1</sec>
 267                            <nanosec>856000</nanosec>
 268                        </leaseAnnouncement>
 269                        <initialAnnouncements>
 270                            <count>10</count>
 271                            <period>
 272                                <nanosec>50</nanosec>
 273                            </period>
 274                        </initialAnnouncements>
 275                        <clientAnnouncementPeriod>
 276                            <nanosec>250000000</nanosec>
 277                        </clientAnnouncementPeriod>
 278                        <static_edp_xml_config>filename1.xml</static_edp_xml_config>
 279                        <static_edp_xml_config>filename2.xml</static_edp_xml_config>
 280                        <static_edp_xml_config>filename3.xml</static_edp_xml_config>
 281                    </discovery_config>
 282
 283                    <avoid_builtin_multicast>true</avoid_builtin_multicast>
 284                    <use_WriterLivelinessProtocol>false</use_WriterLivelinessProtocol>
 285
 286                    <metatrafficUnicastLocatorList>
 287                        <locator>
 288                            <udpv4>
 289                                <!-- Access as physical, like UDP -->
 290                                <port>7400</port>
 291                                <address>192.168.1.41</address>
 292                            </udpv4>
 293                        </locator>
 294                        <locator>
 295                            <tcpv4>
 296                                <!-- Both physical and logical (port), like TCP -->
 297                                <physical_port>5100</physical_port>
 298                                <port>7400</port>
 299                                <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 300                                <wan_address>80.80.99.45</wan_address>
 301                                <address>192.168.1.55</address>
 302                            </tcpv4>
 303                        </locator>
 304                        <locator>
 305                            <udpv6>
 306                                <port>8844</port>
 307                                <address>::1</address>
 308                            </udpv6>
 309                        </locator>
 310                    </metatrafficUnicastLocatorList>
 311
 312                    <metatrafficMulticastLocatorList>
 313                        <locator>
 314                            <udpv4>
 315                                <!-- Access as physical, like UDP -->
 316                                <port>7400</port>
 317                                <address>192.168.1.41</address>
 318                            </udpv4>
 319                        </locator>
 320                        <locator>
 321                            <tcpv4>
 322                                <!-- Both physical and logical (port), like TCP -->
 323                                <physical_port>5100</physical_port>
 324                                <port>7400</port>
 325                                <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 326                                <wan_address>80.80.99.45</wan_address>
 327                                <address>192.168.1.55</address>
 328                            </tcpv4>
 329                        </locator>
 330                        <locator>
 331                            <udpv6>
 332                                <port>8844</port>
 333                                <address>::1</address>
 334                            </udpv6>
 335                        </locator>
 336                    </metatrafficMulticastLocatorList>
 337
 338                    <initialPeersList>
 339                        <locator>
 340                            <udpv4>
 341                                <!-- Access as physical, like UDP -->
 342                                <port>7400</port>
 343                                <address>192.168.1.41</address>
 344                            </udpv4>
 345                        </locator>
 346                        <locator>
 347                            <tcpv4>
 348                                <!-- Both physical and logical (port), like TCP -->
 349                                <physical_port>5100</physical_port>
 350                                <port>7400</port>
 351                                <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 352                                <wan_address>80.80.99.45</wan_address>
 353                                <address>192.168.1.55</address>
 354                            </tcpv4>
 355                        </locator>
 356                        <locator>
 357                            <udpv6>
 358                                <port>8844</port>
 359                                <address>::1</address>
 360                            </udpv6>
 361                        </locator>
 362                    </initialPeersList>
 363
 364                    <metatraffic_external_unicast_locators>
 365                        <udpv4 externality="1" cost="0" mask="24">
 366                            <address>100.100.100.10</address>
 367                            <port>34567</port>
 368                        </udpv4>
 369                    </metatraffic_external_unicast_locators>
 370
 371                    <readerHistoryMemoryPolicy>PREALLOCATED_WITH_REALLOC</readerHistoryMemoryPolicy>
 372                    <writerHistoryMemoryPolicy>PREALLOCATED</writerHistoryMemoryPolicy>
 373                    <readerPayloadSize>512</readerPayloadSize>
 374                    <writerPayloadSize>512</writerPayloadSize>
 375                    <mutation_tries>55</mutation_tries>
 376                    <flow_controller_name>example_flow_controller</flow_controller_name>
 377                </builtin>
 378
 379                <port>
 380                    <portBase>7400</portBase>
 381                    <domainIDGain>200</domainIDGain>
 382                    <participantIDGain>10</participantIDGain>
 383                    <offsetd0>0</offsetd0>
 384                    <offsetd1>1</offsetd1>
 385                    <offsetd2>2</offsetd2>
 386                    <offsetd3>3</offsetd3>
 387                </port>
 388
 389                <participantID>99</participantID>
 390
 391                <userTransports>
 392                    <transport_id>ExampleTransportId1</transport_id>
 393                    <transport_id>ExampleTransportId2</transport_id>
 394                </userTransports>
 395
 396                <useBuiltinTransports>false</useBuiltinTransports>
 397
 398                <builtinTransports max_msg_size="50KB" sockets_size="50KB" non_blocking="false">DEFAULT</builtinTransports>
 399
 400                <propertiesPolicy>
 401                    <properties>
 402                        <property>
 403                            <name>Property1Name</name>
 404                            <value>Property1Value</value>
 405                            <propagate>false</propagate>
 406                        </property>
 407                        <property>
 408                            <name>Property2Name</name>
 409                            <value>Property2Value</value>
 410                            <propagate>false</propagate>
 411                        </property>
 412                    </properties>
 413                </propertiesPolicy>
 414
 415                <allocation>
 416                    <remote_locators>
 417                        <max_unicast_locators>4</max_unicast_locators> <!-- uint32 -->
 418                        <max_multicast_locators>1</max_multicast_locators> <!-- uint32 -->
 419                    </remote_locators>
 420                    <total_participants>
 421                        <initial>0</initial>
 422                        <maximum>0</maximum>
 423                        <increment>1</increment>
 424                    </total_participants>
 425                    <total_readers>
 426                        <initial>0</initial>
 427                        <maximum>0</maximum>
 428                        <increment>1</increment>
 429                    </total_readers>
 430                    <total_writers>
 431                        <initial>0</initial>
 432                        <maximum>0</maximum>
 433                        <increment>1</increment>
 434                    </total_writers>
 435                    <max_partitions>256</max_partitions>
 436                    <max_user_data>256</max_user_data>
 437                    <max_properties>512</max_properties>
 438                    <send_buffers>
 439                        <preallocated_number>127</preallocated_number>
 440                        <dynamic>true</dynamic>
 441                        <network_buffers_config>
 442                            <initial>16</initial>
 443                            <maximum>0</maximum>
 444                            <increment>16</increment>
 445                        </network_buffers_config>
 446                    </send_buffers>
 447                </allocation>
 448
 449                <builtin_controllers_sender_thread>
 450                    <scheduling_policy>-1</scheduling_policy>
 451                    <priority>0</priority>
 452                    <affinity>0</affinity>
 453                    <stack_size>-1</stack_size>
 454                </builtin_controllers_sender_thread>
 455
 456                <timed_events_thread>
 457                    <scheduling_policy>-1</scheduling_policy>
 458                    <priority>0</priority>
 459                    <affinity>0</affinity>
 460                    <stack_size>-1</stack_size>
 461                </timed_events_thread>
 462
 463                <discovery_server_thread>
 464                    <scheduling_policy>-1</scheduling_policy>
 465                    <priority>0</priority>
 466                    <affinity>0</affinity>
 467                    <stack_size>-1</stack_size>
 468                </discovery_server_thread>
 469
 470                <typelookup_service_thread>
 471                    <scheduling_policy>-1</scheduling_policy>
 472                    <priority>0</priority>
 473                    <affinity>0</affinity>
 474                    <stack_size>-1</stack_size>
 475                </typelookup_service_thread>
 476
 477                <builtin_transports_reception_threads>
 478                    <scheduling_policy>-1</scheduling_policy>
 479                    <priority>0</priority>
 480                    <affinity>0</affinity>
 481                    <stack_size>-1</stack_size>
 482                </builtin_transports_reception_threads>
 483
 484                <security_log_thread>
 485                    <scheduling_policy>-1</scheduling_policy>
 486                    <priority>0</priority>
 487                    <affinity>0</affinity>
 488                    <stack_size>-1</stack_size>
 489                </security_log_thread>
 490
 491                <flow_controller_descriptor_list>
 492                    <flow_controller_descriptor>
 493                        <name>example_flow_controller</name>
 494                        <scheduler>FIFO</scheduler>
 495                        <max_bytes_per_period>4096</max_bytes_per_period>
 496                        <period_ms>500</period_ms>
 497                        <sender_thread>
 498                            <scheduling_policy>-1</scheduling_policy>
 499                            <priority>0</priority>
 500                            <affinity>0</affinity>
 501                            <stack_size>-1</stack_size>
 502                        </sender_thread>
 503                    </flow_controller_descriptor>
 504                </flow_controller_descriptor_list>
 505            </rtps>
 506        </participant>
 507
 508        <data_writer profile_name="datawriter_profile_example">
 509            <topic>
 510                <historyQos>
 511                    <kind>KEEP_LAST</kind>
 512                    <depth>20</depth>
 513                </historyQos>
 514                <resourceLimitsQos>
 515                    <max_samples>5</max_samples>
 516                    <max_instances>2</max_instances>
 517                    <max_samples_per_instance>1</max_samples_per_instance>
 518                    <allocated_samples>20</allocated_samples>
 519                    <extra_samples>10</extra_samples>
 520                </resourceLimitsQos>
 521            </topic>
 522            <qos> <!-- dataWriterQosPoliciesType -->
 523                <data_sharing>
 524                    <kind>AUTOMATIC</kind>
 525                    <shared_dir>/home</shared_dir>
 526                    <max_domains>10</max_domains>
 527                    <domain_ids>
 528                        <domainId>0</domainId>
 529                        <domainId>11</domainId>
 530                    </domain_ids>
 531                </data_sharing>
 532                <deadline>
 533                    <period>
 534                        <sec>1</sec>
 535                    </period>
 536                </deadline>
 537                <disable_heartbeat_piggyback>true</disable_heartbeat_piggyback>
 538                <disablePositiveAcks>
 539                    <enabled>true</enabled>
 540                    <duration>
 541                        <sec>1</sec>
 542                    </duration>
 543                </disablePositiveAcks>
 544                <durability>
 545                    <kind>VOLATILE</kind>
 546                </durability>
 547                <!-- QoS policy pending implementation -->
 548                <latencyBudget>
 549                    <duration>
 550                        <sec>1</sec>
 551                    </duration>
 552                </latencyBudget>
 553                <lifespan>
 554                    <duration>
 555                        <sec>5</sec>
 556                    </duration>
 557                </lifespan>
 558                <liveliness>
 559                    <kind>AUTOMATIC</kind>
 560                    <lease_duration>
 561                        <sec>1</sec>
 562                        <nanosec>856000</nanosec>
 563                    </lease_duration>
 564                    <announcement_period>
 565                        <sec>1</sec>
 566                        <nanosec>856000</nanosec>
 567                    </announcement_period>
 568                </liveliness>
 569                <ownership>
 570                    <kind>EXCLUSIVE</kind>
 571                </ownership>
 572                <ownershipStrength>
 573                    <value>50</value>
 574                </ownershipStrength>
 575                <partition>
 576                    <names>
 577                        <name>part1</name>
 578                        <name>part2</name>
 579                    </names>
 580                </partition>
 581                <publishMode>
 582                    <kind>ASYNCHRONOUS</kind>
 583                    <flow_controller_name>example_flow_controller</flow_controller_name>
 584                </publishMode>
 585                <reliability>
 586                    <kind>BEST_EFFORT</kind>
 587                    <max_blocking_time>
 588                        <sec>1</sec>
 589                        <nanosec>856000</nanosec>
 590                    </max_blocking_time>
 591                </reliability>
 592            </qos>
 593
 594            <times>
 595                <initial_heartbeat_delay>
 596                    <sec>1</sec>
 597                    <nanosec>856000</nanosec>
 598                </initial_heartbeat_delay>
 599                <heartbeat_period>
 600                    <sec>1</sec>
 601                    <nanosec>856000</nanosec>
 602                </heartbeat_period>
 603                <nack_response_delay>
 604                    <sec>1</sec>
 605                    <nanosec>856000</nanosec>
 606                </nack_response_delay>
 607                <nack_supression_duration>
 608                    <sec>1</sec>
 609                    <nanosec>856000</nanosec>
 610                </nack_supression_duration>
 611            </times>
 612
 613            <unicastLocatorList>
 614                <locator>
 615                    <udpv4>
 616                        <!-- Access as physical, like UDP -->
 617                        <port>7400</port>
 618                        <address>192.168.1.41</address>
 619                    </udpv4>
 620                </locator>
 621                <locator>
 622                    <tcpv4>
 623                        <!-- Both physical and logical (port), like TCP -->
 624                        <physical_port>5100</physical_port>
 625                        <port>7400</port>
 626                        <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 627                        <wan_address>80.80.99.45</wan_address>
 628                        <address>192.168.1.55</address>
 629                    </tcpv4>
 630                </locator>
 631                <locator>
 632                    <udpv6>
 633                        <port>8844</port>
 634                        <address>::1</address>
 635                    </udpv6>
 636                </locator>
 637            </unicastLocatorList>
 638
 639            <multicastLocatorList>
 640                <locator>
 641                    <udpv4>
 642                        <!-- Access as physical, like UDP -->
 643                        <port>7400</port>
 644                        <address>192.168.1.41</address>
 645                    </udpv4>
 646                </locator>
 647                <locator>
 648                    <tcpv4>
 649                        <!-- Both physical and logical (port), like TCP -->
 650                        <physical_port>5100</physical_port>
 651                        <port>7400</port>
 652                        <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 653                        <wan_address>80.80.99.45</wan_address>
 654                        <address>192.168.1.55</address>
 655                    </tcpv4>
 656                </locator>
 657                <locator>
 658                    <udpv6>
 659                        <port>8844</port>
 660                        <address>::1</address>
 661                    </udpv6>
 662                </locator>
 663            </multicastLocatorList>
 664
 665            <external_unicast_locators>
 666                <udpv4 externality="1" cost="0" mask="24">
 667                    <address>100.100.100.10</address>
 668                    <port>12345</port>
 669                </udpv4>
 670            </external_unicast_locators>
 671
 672            <ignore_non_matching_locators>true</ignore_non_matching_locators>
 673            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
 674
 675            <propertiesPolicy>
 676                <properties>
 677                    <property>
 678                        <name>Property1Name</name>
 679                        <value>Property1Value</value>
 680                        <propagate>false</propagate>
 681                    </property>
 682                    <property>
 683                        <name>Property2Name</name>
 684                        <value>Property2Value</value>
 685                        <propagate>false</propagate>
 686                    </property>
 687                </properties>
 688            </propertiesPolicy>
 689
 690            <userDefinedID>45</userDefinedID>
 691            <entityID>76</entityID>
 692
 693            <matchedSubscribersAllocation>
 694                <initial>3</initial>
 695                <maximum>3</maximum>
 696                <increment>0</increment>
 697            </matchedSubscribersAllocation>
 698        </data_writer>
 699
 700        <data_reader profile_name="datareader_profile_example">
 701            <topic>
 702                <historyQos>
 703                    <kind>KEEP_LAST</kind>
 704                    <depth>20</depth>
 705                </historyQos>
 706                <resourceLimitsQos>
 707                    <max_samples>5</max_samples>
 708                    <max_instances>2</max_instances>
 709                    <max_samples_per_instance>1</max_samples_per_instance>
 710                    <allocated_samples>20</allocated_samples>
 711                    <extra_samples>10</extra_samples>
 712                </resourceLimitsQos>
 713            </topic>
 714            <qos> <!-- dataReaderQosPoliciesType -->
 715                <data_sharing>
 716                    <kind>AUTOMATIC</kind>
 717                    <shared_dir>/home</shared_dir>
 718                    <max_domains>10</max_domains>
 719                    <domain_ids>
 720                        <domainId>0</domainId>
 721                        <domainId>11</domainId>
 722                    </domain_ids>
 723                    <data_sharing_listener_thread>
 724                        <scheduling_policy>-1</scheduling_policy>
 725                        <priority>0</priority>
 726                        <affinity>0</affinity>
 727                        <stack_size>-1</stack_size>
 728                    </data_sharing_listener_thread>
 729                </data_sharing>
 730                <deadline>
 731                    <period>
 732                        <sec>1</sec>
 733                    </period>
 734                </deadline>
 735                <disablePositiveAcks>
 736                    <enabled>true</enabled>
 737                    <duration>
 738                        <sec>1</sec>
 739                    </duration>
 740                </disablePositiveAcks>
 741                <durability>
 742                    <kind>PERSISTENT</kind>
 743                </durability>
 744                <!-- QoS policy pending implementation -->
 745                <latencyBudget>
 746                    <duration>
 747                        <sec>1</sec>
 748                    </duration>
 749                </latencyBudget>
 750                <lifespan>
 751                    <duration>
 752                        <sec>5</sec>
 753                    </duration>
 754                </lifespan>
 755                <liveliness>
 756                    <kind>MANUAL_BY_PARTICIPANT</kind>
 757                    <lease_duration>
 758                        <sec>1</sec>
 759                        <nanosec>856000</nanosec>
 760                    </lease_duration>
 761                    <announcement_period>
 762                        <sec>1</sec>
 763                        <nanosec>856000</nanosec>
 764                    </announcement_period>
 765                </liveliness>
 766                <ownership>
 767                    <kind>EXCLUSIVE</kind>
 768                </ownership>
 769                <partition>
 770                    <names>
 771                        <name>part1</name>
 772                        <name>part2</name>
 773                    </names>
 774                </partition>
 775                <reliability>
 776                    <kind>BEST_EFFORT</kind>
 777                    <max_blocking_time>
 778                        <sec>1</sec>
 779                        <nanosec>856000</nanosec>
 780                    </max_blocking_time>
 781                </reliability>
 782            </qos>
 783
 784            <times>
 785                <initial_acknack_delay>
 786                    <sec>1</sec>
 787                    <nanosec>856000</nanosec>
 788                </initial_acknack_delay>
 789                <heartbeat_response_delay>
 790                    <sec>1</sec>
 791                    <nanosec>856000</nanosec>
 792                </heartbeat_response_delay>
 793            </times>
 794
 795            <unicastLocatorList>
 796                <locator>
 797                    <udpv4>
 798                        <!-- Access as physical, like UDP -->
 799                        <port>7400</port>
 800                        <address>192.168.1.41</address>
 801                    </udpv4>
 802                </locator>
 803                <locator>
 804                    <tcpv4>
 805                        <!-- Both physical and logical (port), like TCP -->
 806                        <physical_port>5100</physical_port>
 807                        <port>7400</port>
 808                        <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 809                        <wan_address>80.80.99.45</wan_address>
 810                        <address>192.168.1.55</address>
 811                    </tcpv4>
 812                </locator>
 813                <locator>
 814                    <udpv6>
 815                        <port>8844</port>
 816                        <address>::1</address>
 817                    </udpv6>
 818                </locator>
 819            </unicastLocatorList>
 820
 821            <multicastLocatorList>
 822                <locator>
 823                    <udpv4>
 824                        <!-- Access as physical, like UDP -->
 825                        <port>7400</port>
 826                        <address>192.168.1.41</address>
 827                    </udpv4>
 828                </locator>
 829                <locator>
 830                    <tcpv4>
 831                        <!-- Both physical and logical (port), like TCP -->
 832                        <physical_port>5100</physical_port>
 833                        <port>7400</port>
 834                        <unique_lan_id>192.168.1.1.1.1.2.55</unique_lan_id>
 835                        <wan_address>80.80.99.45</wan_address>
 836                        <address>192.168.1.55</address>
 837                    </tcpv4>
 838                </locator>
 839                <locator>
 840                    <udpv6>
 841                        <port>8844</port>
 842                        <address>::1</address>
 843                    </udpv6>
 844                </locator>
 845            </multicastLocatorList>
 846
 847            <external_unicast_locators>
 848                <udpv4 externality="1" cost="0" mask="24">
 849                    <address>100.100.100.10</address>
 850                    <port>12345</port>
 851                </udpv4>
 852            </external_unicast_locators>
 853
 854            <ignore_non_matching_locators>true</ignore_non_matching_locators>
 855            <expects_inline_qos>true</expects_inline_qos>
 856            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
 857
 858            <propertiesPolicy>
 859                <properties>
 860                    <property>
 861                        <name>Property1Name</name>
 862                        <value>Property1Value</value>
 863                        <propagate>false</propagate>
 864                    </property>
 865                    <property>
 866                        <name>Property2Name</name>
 867                        <value>Property2Value</value>
 868                        <propagate>false</propagate>
 869                    </property>
 870                </properties>
 871            </propertiesPolicy>
 872
 873            <userDefinedID>55</userDefinedID>
 874            <entityID>66</entityID>
 875
 876            <matchedPublishersAllocation>
 877                <initial>1</initial>
 878                <maximum>1</maximum>
 879                <increment>0</increment>
 880            </matchedPublishersAllocation>
 881        </data_reader>
 882
 883        <topic profile_name="topic_profile_example">
 884            <historyQos>
 885                <kind>KEEP_LAST</kind>
 886                <depth>20</depth>
 887            </historyQos>
 888            <resourceLimitsQos>
 889                <max_samples>5</max_samples>
 890                <max_instances>2</max_instances>
 891                <max_samples_per_instance>1</max_samples_per_instance>
 892                <allocated_samples>20</allocated_samples>
 893                <extra_samples>10</extra_samples>
 894            </resourceLimitsQos>
 895        </topic>
 896    </profiles>
 897
 898    <library_settings>
 899        <intraprocess_delivery>USER_DATA_ONLY</intraprocess_delivery>
 900    </library_settings>
 901
 902    <log>
 903        <use_default>false</use_default>
 904
 905        <consumer>
 906            <class>StdoutConsumer</class>
 907        </consumer>
 908
 909        <consumer>
 910            <class>StdoutErrConsumer</class>
 911            <property>
 912                <name>stderr_threshold</name>
 913                <value>Log::Kind::Warning</value>
 914            </property>
 915        </consumer>
 916
 917        <consumer>
 918            <class>FileConsumer</class>
 919            <property>
 920                <name>filename</name>
 921                <value>execution.log</value>
 922            </property>
 923            <property>
 924                <name>append</name>
 925                <value>TRUE</value>
 926            </property>
 927        </consumer>
 928
 929        <thread_settings>
 930            <scheduling_policy>-1</scheduling_policy>
 931            <priority>0</priority>
 932            <affinity>0</affinity>
 933            <stack_size>-1</stack_size>
 934        </thread_settings>
 935    </log>
 936
 937    <types>
 938        <type> <!-- Types can be defined in its own type of tag or sharing the same tag -->
 939            <enum name="MyAloneEnumType">
 940                <enumerator name="A" value="0"/>
 941                <enumerator name="B" value="1"/>
 942                <enumerator name="C"/>
 943            </enum>
 944        </type>
 945        <type>
 946            <!-- All possible members struct type -->
 947            <struct name="MyFullStruct">
 948                <!-- Primitives & basic -->
 949                <member name="my_bool" type="boolean"/>
 950                <member name="my_char" type="char8"/>
 951                <member name="my_wchar" type="char16"/>
 952                <member name="my_byte" type="byte"/>
 953                <member name="my_octet" type="octet"/>
 954                <member name="my_uint8" type="uint8"/>
 955                <member name="my_short" type="int16"/>
 956                <member name="my_long" type="int32"/>
 957                <member name="my_unsignedshort" type="uint16"/>
 958                <member name="my_unsignedlong" type="uint32"/>
 959                <member name="my_longlong" type="int64"/>
 960                <member name="my_unsignedlonglong" type="uint64"/>
 961                <member name="my_float" type="float32"/>
 962                <member name="my_double" type="float64"/>
 963                <member name="my_longdouble" type="float128"/>
 964                <member name="my_string" type="string"/>
 965                <member name="my_wstring" type="wstring"/>
 966
 967                <!-- string my_boundedString[41925] -->
 968                <member name="my_boundedString" type="string" stringMaxLength="41925"/>
 969                <!-- wstring my_boundedWString[41925] -->
 970                <member name="my_boundedWString" type="wstring" stringMaxLength="41925"/>
 971
 972                <!-- short short_sequence[5]; -->
 973                <member name="short_sequence" sequenceMaxLength="5" type="int16"/>
 974
 975                <!-- long long_array[2][3][4]; -->
 976                <member name="long_array" arrayDimensions="2,3,4" type="int32"/>
 977
 978                <!-- map<long,long,2> my_map_inner -->
 979                <member name="my_map" type="int32" key_type="int32" mapMaxLength="2"/>
 980            </struct>
 981
 982            <typedef name="inner_map" type="char8" key_type="int16"/>
 983            <struct name="MyComplexStruct">
 984                <!-- Complex types -->
 985                <member name="my_other_struct" type="nonBasic" nonBasicTypeName="MyFullStruct"/>
 986                <!-- map<long,map<long,long,2>,2> my_map_map; -->
 987                <member name="my_map_map" type="nonBasic" nonBasicTypeName="inner_map" key_type="int32" mapMaxLength="2"/>
 988            </struct>
 989
 990            <enum name="MyEnum">
 991                <enumerator name="A" value="0"/>
 992                <enumerator name="B" value="1"/>
 993                <enumerator name="C"/>
 994            </enum>
 995
 996            <typedef name="MyAlias1" type="nonBasic" nonBasicTypeName="MyEnum"/>
 997            <typedef name="MyAlias2" type="int32" arrayDimensions="2,2"/>
 998
 999            <struct name="MyStruct">
1000                <member name="first" type="int32"/>
1001                <member name="second" type="int64"/>
1002            </struct>
1003
1004            <!-- TODO(XTypes: Fix inheritance loading from XML profile) Fast DDS#4626 -->
1005            <!-- <struct name="OtherInheritedStruct" baseType="MyStruct">
1006                <member name="my_enum" type="nonBasic" nonBasicTypeName="MyEnum"/>
1007                <member name="my_struct" type="nonBasic" nonBasicTypeName="MyFullStruct" arrayDimensions="5"/>
1008            </struct> -->
1009
1010            <union name="MyUnion1">
1011                <discriminator type="byte"/>
1012                <case>
1013                    <caseDiscriminator value="0"/>
1014                    <caseDiscriminator value="1"/>
1015                    <member name="first" type="int32"/>
1016                </case>
1017                <case>
1018                    <caseDiscriminator value="2"/>
1019                    <member name="second" type="nonBasic" nonBasicTypeName="MyStruct"/>
1020                </case>
1021                <case>
1022                    <caseDiscriminator value="default"/>
1023                    <member name="third" type="int64"/>
1024                </case>
1025            </union>
1026
1027            <bitset name="MyBitSet">
1028                <bitfield name="a" bit_bound="3"/>
1029                <bitfield name="b" bit_bound="10"/>
1030                <bitfield name="c" bit_bound="12" type="int16"/>
1031            </bitset>
1032
1033            <!-- TODO(XTypes: Fix inheritance loading from XML profile) Fast DDS#4626 -->
1034            <!-- <bitset name="OtherInheritedBitSet" baseType="MyBitSet">
1035                <bitfield bit_bound="8"/>
1036                <bitfield bit_bound="15" type="byte"/>
1037            </bitset> -->
1038
1039            <bitmask name="MyBitMask" bit_bound="8">
1040                <bit_value name="flag0" position="0"/>
1041                <bit_value name="flag1"/>
1042            </bitmask>
1043        </type>
1044    </types>
1045</dds>

11. Environment variables

This is the list of environment variables that affect the behavior of Fast DDS:

11.1. FASTDDS_DEFAULT_PROFILES_FILE

Defines the location of the default profile configuration XML file. If this variable is set and its value corresponds with an existing file, Fast DDS will load its profiles. For more information about XML profiles, please refer to XML profiles.

Linux

export FASTDDS_DEFAULT_PROFILES_FILE=/home/user/profiles.xml

Windows

set FASTDDS_DEFAULT_PROFILES_FILE=C:\profiles.xml

11.2. SKIP_DEFAULT_XML

Skips looking for a default profile configuration XML file. If this variable is set to 1, Fast DDS will load the configuration parameters directly from the classes’ definitions without looking for the DEFAULT_FASTDDS_PROFILES.xml in the working directory. For more information about XML profiles, please refer to XML profiles.

Linux

export SKIP_DEFAULT_XML=1

Windows

set SKIP_DEFAULT_XML=1

11.3. FASTDDS_BUILTIN_TRANSPORTS

Setting this variable allows to modify the builtin transports that are initialized during the DomainParticipant creation. It is a simple way of changing the default configuration of the Transport Layer and it directly affects how DDS entities communicate between them.

All existing values, along with a brief description, are shown below:

Builtin Transports Options

Description

NONE

No transport will be instantiated. Hence, the user must manually add the desired
transports. Otherwise, the participant creation will fail.

DEFAULT

UDPv4 and SHM transports will be instantiated. SHM transport has priority over the UDPv4
transport. Meaning that SHM will always be used when possible.

DEFAULTv6

UDPv6 and SHM transports will be instantiated. SHM transport has priority over the UDPv4
transport. Meaning that SHM will always be used when possible.

SHM

Only a SHM transport will be instantiated.

UDPv4

Only a UDPv4 transport will be instantiated.

UDPv6

Only a UDPv6 transport will be instantiated.

LARGE_DATA

UDPv4, TCPv4, and SHM transports will be instantiated. However, UDP will only be used
for multicast announcements during the participant discovery phase (see Discovery phases)
while the participant liveliness and the application data delivery occurs over TCP or SHM.
This configuration is useful when working with large data.(See Large Data mode and Fast DDS over TCP).

Note

The environment variable is only used in the case where use_builtin_transports is set to TRUE. In any other case, the environment variable has no effect.

Note

TCPv4 transport is initialized with the following configuration:

11.3.1. Configuring builtin transports options

Fast DDS offers a straightforward method to configure three main parameters of every builtin transport via the environment variable. However, this feature proves particularly valuable when employing the LARGE_DATA builtin transports option. The LARGE_DATA mode has been designed to improve performance when working with large data. However, according to each specific use case, the user might want to configure several options to better fit their needs. This mode can also be configured with the tcp_negotiation_timeout parameter:

Builtin Transports Options

Description

Type

max_msg_size

It determines the maximum message size that will be specified
in the transport layer. Selecting a message size large
enough to accommodate the largest data message will
prevent fragmentation, which can significantly enhance
the overall sending rate.

uint32_t

sockets_size

It determines the size of the send and receive socket buffers.
This parameter needs to be higher or equal to the maximum
message size specified in order to be valid.

uint32_t

non_blocking

It determines whether to use non-blocking send calls or not.
When activated, the transport will discard messages if the
socket buffers are full.

bool

tcp_negotiation_timeout

It determines the time to wait for logical port negotiation.
Only valid if the LARGE_DATA mode is being used.
It only accepts milliseconds.

uint32_t

The environment variable accepts several types of units to specify the values of the parameters. Also, both lowercase and uppercase letters are valid. The following list shows the available units and their corresponding symbols:

  • B: Bytes. This is the default unit, so it is not necessary to specify it.

  • KB: Kilobytes.

  • MB: Megabytes.

  • GB: Gigabytes.

  • KIB: Kibibyte.

  • MIB: Mebibyte.

  • GIB: Gibibyte.

export FASTDDS_BUILTIN_TRANSPORTS=LARGE_DATA?max_msg_size=200KB&sockets_size=1MB&non_blocking=true&tcp_negotiation_timeout=50

Note

When working with LARGE_DATA, it is recommended to set the max_msg_size and sockets_size to a value large enough to accommodate the largest data message and to set the non_blocking to TRUE. Note that activating the non_blocking option with a small message size (with fragmentation) can lead to an increase of messages drop rate and produce undesired results. For more information, please refer to Large Data with configuration options.

Warning

Setting a max_msg_size higher than 65500 KB is only possible when using the LARGE_DATA builtin transports option. Trying to set it with any other builtin transports will result in an error and the creation of the participant will fail.

11.4. ROS_DISCOVERY_SERVER

Warning

The environment variable is only used in the case where discovery protocol is set to SIMPLE, SERVER, or BACKUP. In any other case, the environment variable has no effect.

Setting this variable configures the DomainParticipant to connect to one or more servers using the Discovery Server discovery mechanism.

  • If ROS_DISCOVERY_SERVER is defined, and the DomainParticipant’s discovery protocol is set to SIMPLE, then Fast DDS will instead configure it as CLIENT of the given server.

  • If ROS_DISCOVERY_SERVER is defined, and the DomainParticipant’s discovery protocol is set to SERVER or BACKUP, then the variable is used to add remote servers to the given server, leaving the discovery protocol as SERVER or BACKUP respectively.

  • The value of the variable must list the locator of the server in the form of:

    • An IPv4 address like 192.168.2.23. The UDP protocol is used by default. The UDP port can be appended using : as in 192.168.2.23:35665.

    • An IPv6 address that follows RFC3513 address convention like 1080::8:800:200C:417A. Again, it uses the UDP protocol by default. An UDP port can be appended like in [1080::8:800:200C:417A]:35665. Note the use of square brackets to avoid ambiguities.

    • TCPv4 specifier + IPv4 address like TCPv4:[127.0.0.1]. The TCP protocol is used to communicate with the server. The TCP port can be appended using : as in TCPv4:[127.0.0.1]:42100.

    • TCPv6 specifier + IPv6 address like TCPv6:[::1]. The TCP protocol is used to communicate with the server. The TCP port can be appended using : as in TCPv6:[::1]:42100.

    • A DNS name can be specified. This name will be used to query known hosts and available DNS servers to try to resolve valid IP addresses. Several formats are acceptable:

      • Plain domain name: eprosima.com. This will include all available IP addresses.

      • Domain name + port: eprosima.com:35665. As above but using a specific port.

      • UDPv4 specifier + domain name: UDPv4:[eprosima.com]. Only the first IPv4 address resolved will be used.

      • UDPv4 specifier + domain name + port: UDPv4:[eprosima.com]:35665. As above but using a specific port.

      • UDPv6 specifier + domain name: UDPv6:[<dns>]. Only the first IPv6 address resolved will be used.

      • UDPv6 specifier + domain name + port: UDPv6:[<dns>]:35665. As above but using a specific port.

      • TCPv4 specifier + domain name: TCPv4:[eprosima.com]. Only the first IPv4 address resolver will be used.

      • TCPv4 specifier + domain name + port: TCPv4:[eprosima.com]:42100. As above but using a specific port.

      • TCPv6 specifier + domain name: TCPv6:[<dns>]. Only the first IPv4 address resolver will be used.

      • TCPv6 specifier + domain name + port: TCPv6:[<dns>]:42100. As above but using a specific port.

  • If no port is specified when using default UDP transport, the default port 11811 is used.

  • If no port is specified when using TCP transport, the default port 42100 is used.

  • To set more than one server’s address, they must be separated by semicolons.

  • When using IPv6 with DNS, the specified domain name space (<dns>) must be able to resolve to an IPv6 address. Otherwise an error will be raised.

The following example shows how to set the address of two remote discovery servers with addresses ‘84.22.259.329:8888’ and ‘localhost:1234’.

Linux

export ROS_DISCOVERY_SERVER="84.22.259.329:8888;localhost:1234"

Windows

set ROS_DISCOVERY_SERVER=84.22.259.329:8888;localhost:1234

Important

IP addresses specified in ROS_DISCOVERY_SERVER must be either valid IPv4/IPv6 addresses or domain names. If a name can be resolved into several addresses, it is possible to either use them all or restrict the selection to the first IPv4 using the UDPv4 or TCPv4 prefixes or to the first IPv6 address using the UDPv6 or TCPv6 prefixes.

Important

This environment variable can be changed at runtime adding new remote servers to a SERVER, BACKUP or CLIENT (that has been initialized with this environment variable previously) if loaded from an environment file using FASTDDS_ENVIRONMENT_FILE.

11.5. ROS2_EASY_MODE

Setting ROS2_EASY_MODE to an IP value allows a participant to automatically enter the Discovery Server Easy Mode. This mode completely disables multicast communication, and relies on Discovery Servers for discovery purposes.

With ROS2_EASY_MODE a new Discovery Server will be automatically spawned locally in the given domain, pointing to another Discovery Server located in the specified IP. If the specified IP belongs to the same host, it will only work in localhost, until another host connects to it. If there exists a Discovery Server for that domain, the spawn process will be skipped, relying on the existing server for discovery purposes. Therefore, only one Discovery Server per host will be present in the domain.

In order for this variable to take effect, the participant must have its discovery protocol set to SIMPLE (default), to automatically enter the Discovery Server Easy Mode. If this happens, the participant will be configured as a SUPER_CLIENT pointing to the local server.

The following example will configure participants as SUPER_CLIENT pointing to a local Discovery Server, which will try to connect to another Discovery Server located in the host 10.0.0.1.

export ROS2_EASY_MODE=10.0.0.1

The port of the Discovery Server is calculated using the rules explained in the Well Known Ports. The transports configured in this new mode include UDP unicast for discovery and TCP and Shared Memory for user data.

A detailed tutorial can be found in the Vucanexus Easy Mode Tutorial documentation.

Note

When ROS2_EASY_MODE is enabled, Fast DDS automatically loads a custom XML profile named service. This profile increases the server’s response timeout for ROS 2 services by modifying the max_blocking_time. However, if the user provides an XML file that already contains a profile with the same name, Fast DDS will not load any extra profile. Instead, the max_blocking_time value defined in the user’s XML file will be used.

Warning

Discovery Server ROS2_EASY_MODE is not yet available for Windows platforms.

11.6. ROS_SUPER_CLIENT

If the DomainParticipant’s discovery protocol is set to SIMPLE, and ROS_SUPER_CLIENT is set to TRUE, the participant is automatically promoted to a SUPER_CLIENT.

Important

This environment variable is meant to be used in combination with ROS_DISCOVERY_SERVER to promote a participant from SIMPLE to SUPER_CLIENT. The participant will have the servers list defined in ROS_DISCOVERY_SERVER.

The possible values are: TRUE, true, True, 1, FALSE, false, False, 0.

Important

If the variable is not set, the default behavior of Fast DDS is equivalent to the case in which the variable is set to false.

The following example shows how to set the environment variable to true.

Linux

export ROS_SUPER_CLIENT=TRUE

Windows

set ROS_SUPER_CLIENT=TRUE

11.7. FASTDDS_STATISTICS

Warning

The environment variable is only used in the case where the CMake option FASTDDS_STATISTICS has been enabled. In any other case, the environment variable has no effect. Please, refer to CMake options for more information.

Setting this variable configures the DomainParticipant to enable the statistics DataWriters which topics are contained in the list set in this environment variable. The elements of the list should be separated by semicolons and match the statistics topic name aliases.

For example, to enable the statistics DataWriters that report the latency measurements, the environment variable should be set as follows:

Linux

export FASTDDS_STATISTICS="HISTORY_LATENCY_TOPIC;NETWORK_LATENCY_TOPIC"

Windows

set FASTDDS_STATISTICS=HISTORY_LATENCY_TOPIC;NETWORK_LATENCY_TOPIC

Important

This environment variable can be used together with the XML profiles (for more information please refer to Automatically enabling statistics DataWriters). The statistics DataWriters that will be enabled is the union between the ones specified in the XML file (if loaded) and the ones stated in the environment variable (if set).

11.8. FASTDDS_ENVIRONMENT_FILE

Setting this environment variable to an existing json file allows to load the environment variables from the file instead of from the environment. This allows to change the value of some environment variables at run time with just modifying and saving the changes to the file. The environment value can be either an absolute or relative path. The file format is as follows:

{
    "environment_variable_name_1": "environment_variable_value_1",
    "environment_variable_name_2": "environment_variable_value_2"
}

Important

The environment variables set in the environment file have precedence over the environment.

Warning

Currently only ROS_DISCOVERY_SERVER environment variable allows for changes at run time. (see Modifying remote servers list at run time)

12. PropertyPolicyQos Options

This section contains the list of PropertyPolicyQos that can be set with Fast DDS:

12.1. Non consolidated QoS

The PropertyPolicyQos Options are used to develop new eProsima Extensions QoS. Before consolidating a new QoS Policy, it is usually set using this generic QoS Policy. Consequently, this section is prone to frequent updates so the user is advised to check latest changes after upgrading to a different release version.

12.1.1. DataWriter operating mode QoS Policy

By default, Fast DDS DataWriters are enabled using push mode. This implies that they will add new samples into their queue, and then immediately deliver them to matched readers. For writers that produce non periodic bursts of data, this may imply saturating the network with a lot of packets, increasing the possibility of losing them on unreliable (i.e. UDP) transports. Depending on their QoS, DataReaders may also have to ignore some received samples, so they will have to be resent.

Configuring the DataWriters on pull mode offers an alternative by letting each reader pace its own data stream. It works by the writer notifying the reader what it is available, and waiting for it to request only as much as it can handle. At the cost of greater latency, this model can deliver reliability while using far fewer packets than push mode.

DataWriters periodically announce the state of their queue by means of a heartbeat. Upon reception of the heartbeat, DataReaders will request the DataWriter to send the samples they want to process. Consequently, the publishing rate can be tuned setting the heartbeat period accordingly. See Tuning Heartbeat Period for more details.

PropertyPolicyQos name

PropertyPolicyQos value

Default value

"fastdds.push_mode"

"true"/"false"

"true"

DataWriterQos wqos;

// Enable pull mode
wqos.properties().properties().emplace_back(
    "fastdds.push_mode",
    "false");
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
<data_writer profile_name="pull_mode_datawriter_xml_profile">
    <propertiesPolicy>
        <properties>
            <!-- Enable pull mode -->
            <property>
                <name>fastdds.push_mode</name>
                <value>false</value>
            </property>
        </properties>
    </propertiesPolicy>
</data_writer>
</profiles>

Note

Warning

12.1.2. Unique network flows QoS Policy

Warning

This section is still under work.

12.1.3. Statistics Module Settings

Fast DDS Statistics Module uses the PropertyPolicyQos to indicate the statistics DataWriters that are enabled automatically (see Automatically enabling statistics DataWriters). In this case, the property value is a semicolon separated list containing the statistics topic name aliases of those DataWriters that the user wants to enable.

PropertyPolicyQos name

PropertyPolicyQos value

Default value

"fastdds.statistics"

Semicolon separated list of statistics topic name aliases

""

DomainParticipantQos pqos;

// Activate Fast DDS Statistics module
pqos.properties().properties().emplace_back("fastdds.statistics",
        "HISTORY_LATENCY_TOPIC;ACKNACK_COUNT_TOPIC;DISCOVERY_TOPIC;PHYSICAL_DATA_TOPIC");
<participant profile_name="statistics_domainparticipant_conf_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Activate Fast DDS Statistics Module -->
                <property>
                    <name>fastdds.statistics</name>
                    <value>HISTORY_LATENCY_TOPIC;ACKNACK_COUNT_TOPIC;DISCOVERY_TOPIC;PHYSICAL_DATA_TOPIC</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>
12.1.3.1. Physical Data in Discovery Information

It is possible to include the information conveyed in the PHYSICAL_DATA_TOPIC into the participant discovery message, a.k.a DATA[p] (see Discovery phases). This is done by setting the following properties within the PropertyPolicyQos:

PropertyPolicyQos name

PropertyPolicyQos value

Default value without
FASTDDS_STATISTICS

Default value with
FASTDDS_STATISTICS

"fastdds.physical_data.host"

Name of the host computer in which
the application runs

Not set

""

"fastdds.physical_data.user"

Name of the user running the application

Not set

""

"fastdds.physical_data.process"

Name of the process running the application

Not set

""

Whenever any of these properties is defined within the DomainParticipantQos, the DomainParticipant DATA[p] will contained the set value. Furthermore, if any of these properties is set to a value of "", which is the default when FASTDDS_STATISTICS is defined (see CMake options), Fast DDS will automatically populate the value using the following convention:

  • "fastdds.physical_data.host": Host name as returned by asio::ip::host_name(), followed by ":<default data sharing domain id>"

  • "fastdds.physical_data.user": Name of the user running the application, or "unknown" if it could not be retrieved.

  • "fastdds.physical_data.process": The process ID of the process in which the application is running.

All the previous entails that adding physical information to the DATA[p] can be done regardless of whether FASTDDS_STATISTICS is defined, and that it is possible to let Fast DDS set some default values into the reported host, user, and process:

  1. If FASTDDS_STATISTICS is defined, and the user does not specify otherwise, Fast DDS will set default values to the physical properties of the DATA[p].

  2. If FASTDDS_STATISTICS is defined, and the user sets values to the properties, the user settings are honored.

  3. If FASTDDS_STATISTICS is defined, and the user removes the physical properties from the DomainParticipantQos, then no physical information is transmitted in the DATA[p].

  4. If FASTDDS_STATISTICS is not defined, it is still possible to transmit physical information in the DATA[p] by setting the aforementioned properties:

    1. If set to "", then Fast DDS will populate their value according to the described rules.

    2. If set to something other than "", then the set value will be transmitted in the DATA[p] as-is.

In case FASTDDS_STATISTICS is defined, and the reporting of statistics over the DISCOVERY_TOPIC is enabled (see Statistics Module Settings), then the physical information included in the DATA[p] is also transmitted over the DISCOVERY_TOPIC (see PHYSICAL_DATA_TOPIC) whenever one DomainParticipant discovers another one.

/* Create participant which announces default physical properties */
DomainParticipantQos pqos_default_physical;
// NOTE: If FASTDDS_STATISTICS is defined, then setting the properties to "" is not necessary
pqos_default_physical.properties().properties().emplace_back("fastdds.physical_data.host", "");
pqos_default_physical.properties().properties().emplace_back("fastdds.physical_data.user", "");
pqos_default_physical.properties().properties().emplace_back("fastdds.physical_data.process", "");
DomainParticipant* participant_with_physical = DomainParticipantFactory::get_instance()->create_participant(0,
                pqos_default_physical);

/* Create participant which announces custom physical properties */
DomainParticipantQos pqos_custom_physical;
// NOTE: If FASTDDS_STATISTICS is defined, then clear the properties before setting them
// pqos_custom_physical.properties().properties().clear()
pqos_custom_physical.properties().properties().emplace_back("fastdds.physical_data.host", "custom_hostname");
pqos_custom_physical.properties().properties().emplace_back("fastdds.physical_data.user", "custom_username");
pqos_custom_physical.properties().properties().emplace_back("fastdds.physical_data.process", "custom_process");
DomainParticipant* participant_custom_physical = DomainParticipantFactory::get_instance()->create_participant(0,
                pqos_custom_physical);

/* Create participant which does not announce physical properties */
DomainParticipantQos pqos_no_physical;
pqos_no_physical.properties().properties().clear();
DomainParticipant* participant_without_physical = DomainParticipantFactory::get_instance()->create_participant(
    0, pqos_no_physical);

/* Load physical properties from default XML file */
DomainParticipantFactory::get_instance()->load_profiles();
DomainParticipantQos pqos_default_xml_physical =
        DomainParticipantFactory::get_instance()->get_default_participant_qos();
DomainParticipant* participant_default_xml_physical =
        DomainParticipantFactory::get_instance()->create_participant(0, pqos_default_xml_physical);

/* Load physical properties from specific XML file */
DomainParticipantFactory::get_instance()->load_XML_profiles_file("somefile.xml");
DomainParticipantFactory::get_instance()->load_profiles();
DomainParticipantQos pqos_custom_xml_physical =
        DomainParticipantFactory::get_instance()->get_default_participant_qos();
DomainParticipant* participant_custom_xml_physical =
        DomainParticipantFactory::get_instance()->create_participant(0, pqos_custom_xml_physical);
<?xml version="1.0" encoding="utf-8"?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="statistics_participant" is_default_profile="true">
            <rtps>
                <propertiesPolicy>
                    <properties>
                        <property>
                            <name>fastdds.physical_data.host</name>
                            <value>custom_hostname</value>
                        </property>
                        <property>
                            <name>fastdds.physical_data.user</name>
                            <value>custom_username</value>
                        </property>
                        <property>
                            <name>fastdds.physical_data.process</name>
                            <value>custom_process</value>
                        </property>
                    </properties>
                </propertiesPolicy>
            </rtps>
        </participant>
    </profiles>
</dds>

Important

The properties set using XML override those in the default QoS, which means that it is possible to set the physical properties using XML regardless of whether FASTDDS_STATISTICS is defined. However, it is not possible to remove the properties using XML, meaning that an application using Fast DDS with FASTDDS_STATISTICS enabled which does not want for the physical information to be transmitted in the DomainParticipant DATA[p] must remove the properties using the aforementioned C++ API.

12.1.4. Endpoint Partitions

Fast DDS uses this PropertyPolicyQos to define which partitions does an endpoint belong to. This property follows the same logic regarding matching as the PartitionQosPolicy that can be defined for Publishers and Subscribers.

This property’s value is a semicolon separated list containing the partition names the user wants this endpoint to belong to.

Important

If both a Publisher and one of its DataWriters have conflicting partition configuration, this is, a DataWriter has this property defined while the Publisher has the PartitionQosPolicy defined, the DataWriter configuration takes precedence and the Publisher PartitionQosPolicy is ignored for this endpoint. This applies to Subscribers and their DataReaders as well.

This property will be automatically set when creating DataReaders and DataWriters using the create_with_profile functions. It cannot be changed after the entity has been created.

PropertyPolicyQos name

PropertyPolicyQos value

Default value

"partitions"

Semicolon separated list of partition names

""

DataWriterQos wqos;

// Add partitions
wqos.properties().properties().emplace_back(
    "partitions",
    "part1;part2");

DataReaderQos rqos;

// Add partitions
rqos.properties().properties().emplace_back(
    "partitions",
    "part1;part2");
<data_writer profile_name="pub_partition_example">
    <qos>
        <partition>
            <names>
                <name>part1</name>
                <name>part2</name>
            </names>
        </partition>
    </qos>
</data_writer>

<data_reader profile_name="sub_partition_example">
    <qos>
        <partition>
            <names>
                <name>part1</name>
                <name>part2</name>
            </names>
        </partition>
    </qos>
</data_reader>

12.1.5. Static Discovery’s Exchange Format

Static Discovery exchanges data in the Participant Discovery Phase (PDP). Currently there are two different exchange formats which can be selected using the property dds.discovery.static_edp.exchange_format.

PropertyPolicyQos value

Description

Default

"v1"

Standard exchange format for Static Discovery.

"v1_Reduced"

Format which reduces the necessary network bandwidth to transmit Static
Discovery’s information in the Participant Discovery Phase (PDP).

DomainParticipantQos participant_qos;
participant_qos.properties().properties().emplace_back(
    "dds.discovery.static_edp.exchange_format",
    "v1_Reduced"
    );
<participant profile_name="participant_xml_conf_static_discovery_format_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <property>
                    <name>dds.discovery.static_edp.exchange_format</name>
                    <value>v1_Reduced</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>

12.1.6. SHM transport meta-traffic enforcement

A DomainParticipant will by default configure both a UDP Transport and a Shared Memory Transport. When a participant on another process in the same host is discovered, the endpoint discovery might be done using either transport.

Avoiding Shared Memory communication for discovery traffic can save valuable resources. The behavior regarding this can be configured using the property fastdds.shm.enforce_metatraffic.

PropertyPolicyQos value

Description

Default

"none"

Use other transports for meta-traffic.

"unicast"

Enable SHM transport unicast communications.

"all"

Enable SHM transport unicast and multicast communications.
This will enable discovery between SHM only participants
and participants having several transports.

Note

When SHM is the only transport configured for a participant, the setting of this property is ignored, and considered to be "all".

DomainParticipantQos participant_qos;

// SHM transport will listen for unicast meta-traffic
participant_qos.properties().properties().emplace_back(
    "fastdds.shm.enforce_metatraffic",
    "unicast");
<participant profile_name="participant_xml_conf_shm_enforce_metatraffic_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <property>
                    <name>fastdds.shm.enforce_metatraffic</name>
                    <value>unicast</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>

12.1.7. Maximum Message Size

One common requirement is the differentiation between the maximum size of received and sent datagrams. This capability is especially important in scenarios where a system might need to handle large incoming data sizes but should restrict the size of the data it sends to prevent overwhelming network resources or complying with network traffic policies. The primary attribute for controlling datagram size is maxMessageSize, which sets the upper limit for both the size of datagrams that can be received and those that can be sent. Property fastdds.max_message_size allows restricting the size of outgoing datagrams without changing the size of incoming ones. This property allows for the specific configuration of the maximum number of bytes for datagrams that are sent. By configuring this property to a value lower than the smallest maxMessageSize across all transports, applications can achieve a lower sending limit while maintaining the ability to receive larger datagrams.

PropertyPolicyQos name

PropertyPolicyQos value

Default value

"fastdds.max_message_size"

uint32_t

"4294967295"

Note

An invalid value of fastdds.max_message_size would log an error, and the default value will be used.

12.1.7.1. Setting fastdds.max_message_size At Participant Level
DomainParticipantQos pqos;

// Set maximum number of bytes of the datagram to be sent
pqos.properties().properties().emplace_back(
    "fastdds.max_message_size",
    "1200");
<?xml version="1.0" encoding="UTF-8" ?>
<participant profile_name="max_message_size_participant_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Set the maximum size in bytes for all RTPS datagrams sent by the participant -->
                <property>
                    <name>fastdds.max_message_size</name>
                    <value>1200</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>
12.1.7.2. Setting fastdds.max_message_size At Writer Level
DataWriterQos wqos;

// Set maximum number of bytes of the datagram to be sent
wqos.properties().properties().emplace_back(
    "fastdds.max_message_size",
    "1200");
<?xml version="1.0" encoding="UTF-8" ?>
<data_writer profile_name="max_msg_size_datawriter_xml_profile">
    <propertiesPolicy>
        <properties>
            <!-- Set the maximum size in bytes for all RTPS datagrams sent by the writer -->
            <property>
                <name>fastdds.max_message_size</name>
                <value>1200</value>
            </property>
        </properties>
    </propertiesPolicy>
</data_writer>

12.1.8. Type Propagation

By default, Fast DDS leverages Remote Data Types Discovery both to discover remote types and to propagate local ones. Type propagation entails both adding meta-information to the EDP messages (see Discovery phases) and using a dedicated set of builtin endpoints to transmit type definitions between the different DomainParticipants in the network.

Depending on the application design and deployment, it might be desirable to change the default type propagation behavior to save bandwidth and/or resources. For this reason, Fast DDS DomainParticipants can be configured with a property fastdds.type_propagation that controls how type information is propagated.

PropertyPolicyQos name

PropertyPolicyQos value

Default value

"fastdds.type_propagation"

"disabled"
"enabled"
"minimal_bandwidth"
"registration_only"

"enabled"

The different property values have the following effects on the local DomainParticipant:

Value

TypeObject registration

Send type information on EDP

Receive type information on EDP

Type lookup service replies

"disabled"

NO

NO

IGNORED

DISABLED

"enabled"

COMPLETE and MINIMAL

COMPLETE and MINIMAL

PROCESSED

ENABLED

"minimal_bandwidth"

MINIMAL only

MINIMAL only

Only MINIMAL PROCESSED

ENABLED

"registration_only"

COMPLETE and MINIMAL

COMPLETE and MINIMAL

IGNORED

DISABLED

DomainParticipantQos pqos;

pqos.properties().properties().emplace_back(
    "fastdds.type_propagation",
    "disabled");
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="type_propagation_domainparticipant_xml_profile">
            <rtps>
                <propertiesPolicy>
                    <properties>
                        <property>
                            <name>fastdds.type_propagation</name>
                            <value>disabled</value>
                        </property>
                    </properties>
                </propertiesPolicy>
            </rtps>
        </participant>
    </profiles>
</dds>

12.2. Flow Controller Settings

When using Flow Controllers, the DataWriter may need specific parameters to be set. Properties related with this feature lie on the fastdds.sfc namespace.

  • Property fastdds.sfc.priority is used to set the priority of the DataWriter for HIGH_PRIORITY and PRIORITY_WITH_RESERVATION flow controllers. Allowed values are from -10 (highest priority) to 10 (lowest priority). If the property is not present, it will be set to the lowest priority.

  • Property fastdds.sfc.bandwidth_reservation is used to set the percentage of the bandwidth that the DataWriter is requesting for PRIORITY_WITH_RESERVATION flow controllers. Allowed values are from 0 to 100, and express a percentage of the total flow controller limit. If the property is not present, it will be set to 0 (no bandwidth is reserved for the DataWriter).

12.3. Persistence Service Settings

Warning

This section is still under work.

12.4. Security Plugins Settings

As described in the Security section, the security plugins admit a set of settings that can be configured.

12.4.1. Authentication plugin settings

The DDS:Auth:PKI-DH authentication plugin, can be activated setting the DomainParticipantQos properties() dds.sec.auth.plugin with the value builtin.PKI-DH. The following table outlines the properties used for the DDS:Auth:PKI-DH plugin configuration.

PropertyPolicyQos name

PropertyPolicyQos value

identity_ca

URI to the X.509 v3 certificate of the Identity CA in PEM format.
Supported URI schemes: file.

identity_certificate

URI to an X.509 v3 certificate signed by the Identity CA in PEM format
containing the signed public key for the Participant.
Supported URI schemes: file.

identity_crl (optional)

URI to a X.509 Certificate Revocation List (CRL).
Supported URI schemes: file.

private_key

URI to access the private Private Key for the Participant.
Supported URI schemes: file, PKCS#11.

password (optional)

A password used to decrypt the private_key.
If the password property is not present, then the value supplied in the
private_key property must contain the decrypted private key.
The password property is ignored if the private_key is given in PKCS#11 scheme.

preferred_key_agreement (optional)

The preferred algorithm to use for generating the session’s shared secret
at the end of the authentication phase. Supported values are:
a) DH, DH+MODP-2048-256 for Diffie-Hellman Ephemeral with 2048-bit MODP Group parameters.
b) ECDH, ECDH+prime256v1-CEUM for Elliptic Curve Diffie-Hellman Ephemeral with the NIST P-256 curve.
c) AUTO for selecting the key agreement based on the signature algorithm in the Identity CA’s certificate.
Will default to AUTO if the property is not present.

transmit_algorithms_as_legacy (optional)

Whether to transmit algorithm identifiers in non-standard legacy format.
Will default to false if the property is not present.

Note

All properties listed above have the dds.sec.auth.builtin.PKI-DH." prefix. For example: dds.sec.auth.builtin.PKI-DH.identity_ca. For examples and further information, please refer to the Authentication plugin: DDS:Auth:PKI-DH section.

12.4.2. Authentication handshake settings

The authentication phase starts when discovery information is received from the remote DomainParticipants. At this moment, the participant sends a handshake request until a handshake response is received from the remote participant. Some parameters are involved in the behavior of this exchange:

  • max_handshake_requests controls the maximum number of handshake requests to be sent.

  • initial_handshake_resend_period represents the initial waiting time (in milliseconds) for the first handshake request that has to be resent.

  • handshake_resend_period_gain is the gain against which the period is multiplied between two handshake requests.

Hence, the period of time to wait for sending a new handshake request is computed at each iteration as the period between the last two handshake requests multiplied by the gain (so that the period increases).

The following table lists the settings to configure the authentication handshake behavior within the dds.sec.auth.builtin.PKI-DH plugin:

PropertyPolicyQos name

PropertyPolicyQos value

PropertyPolicyQos bounds

Default value

max_handshake_requests

<int>

[1, max)

10

initial_handshake_resend_period

<int>

[1, max)

125

handshake_resend_period_gain

<double>

(1.0, max)

1.5

Note

All listed properties have the dds.sec.auth.builtin.PKI-DH. prefix. For example: dds.sec.auth.builtin.PKI-DH.max_handshake_requests.

The following is an example of how to set the properties of DomainParticipantQoS for the authentication handshake configuration.

DomainParticipantQos pqos;

pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.max_handshake_requests",
    "5");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.initial_handshake_resend_period",
    "250");
pqos.properties().properties().emplace_back(
    "dds.sec.auth.builtin.PKI-DH.handshake_resend_period_gain",
    "1.5");
<participant profile_name="secure_domainparticipant_conf_auth_handshake_props_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.max_handshake_requests</name>
                    <value>5</value>
                </property>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.initial_handshake_resend_period</name>
                    <value>250</value>
                </property>
                <property>
                    <name>dds.sec.auth.builtin.PKI-DH.handshake_resend_period_gain</name>
                    <value>1.5</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>

12.4.3. Cryptographic plugin settings

The DDS:Crypto:AES-GCM-GMAC authentication plugin, can be activated setting the DomainParticipantQos properties() dds.sec.crypto.plugin with the value builtin.AES-GCM-GMAC. Moreover, this plugin needs the activation of the Authentication plugin: DDS:Auth:PKI-DH. The DDS:Crypto:AES-GCM-GMAC plugin is configured using the Access control plugin: DDS:Access:Permissions, i.e the cryptography plugin is configured through the properties and configuration files of the access control plugin. For further information and examples in this regard please refer to Cryptographic plugin: DDS:Crypto:AES-GCM-GMAC.

12.4.4. Logging plugin settings

The DDS:Logging:DDS_LogTopic authentication plugin, can be activated setting the DomainParticipantQos properties() dds.sec.log.plugin with the value builtin.DDS_LogTopic. The following table outlines the properties used for the DDS:Logging:DDS_LogTopic plugin configuration. For further information and examples follow the dedicated documentation: Logging plugin: DDS:Logging:DDS_LogTopic.

12.5. Logging Module Settings

Warning

This section is still under work.

12.6. Ignore Local Endpoints

By default, Fast DDS will automatically match all the endpoints (meaning DataReaders and DataWriters) belonging to a given DomainParticipant as soon as they share the same Topic and have compatible Qos. This however can result in undesired feedback whenever an application creates a DataReader and a DataWriter under the same DomainParticipant on a shared Topic. Although this feedback can be filtered out at the application level upon data reception by filtering out messages coming from a DataWriter belonging to the same DomainParticipant on the DataReader receiving the data (by looking at the GuidPrefix_t), this entails for a data sample to go all the way to the DataReaderListener just to be discarded by an overcomplicated application business logic. For this reason, Fast DDS offers the possibility of instructing the DomainParticipant to avoid the matching of local endpoints through the following property:

PropertyPolicyQos name

PropertyPolicyQos value

Default value

"fastdds.ignore_local_endpoints"

"true"/"false"

"false"

DomainParticipantQos participant_qos;

// Avoid local matching of this participant's endpoints
participant_qos.properties().properties().emplace_back(
    "fastdds.ignore_local_endpoints",
    "true");
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="ignore_local_endpoints_domainparticipant_xml_profile">
            <rtps>
                <propertiesPolicy>
                    <properties>
                        <!-- Avoid local matching of this participant's endpoints -->
                        <property>
                            <name>fastdds.ignore_local_endpoints</name>
                            <value>true</value>
                        </property>
                    </properties>
                </propertiesPolicy>
            </rtps>
        </participant>
    </profiles>
</dds>

Note

An invalid value of fastdds.ignore_local_endpoints results in the default behaviour.

13. Statistics Module

The Fast DDS Statistics module is an extension of Fast DDS that enables the recollection of data concerning the DDS communication. The collected data is published using DDS over dedicated topics using builtin DataWriters within the Statistics module. Consequently, by default, Fast DDS does not compile this module because it may entail affecting the application’s performance. Nonetheless, the Statistics module and the Monitor Service can be activated using the -DFASTDDS_STATISTICS=ON at CMake configuration step. For more information about Fast DDS compilation, see Linux installation from sources and Windows installation from sources.

Besides enabling the Statistics Module compilation, the user must enable those DataWriters that are publishing data on the topics of interest for the user’s application. Therefore, the standard DDS Layer has been extended. The following section explains this DDS extended API.

Note

Please refer to Statistics QoS Troubleshooting for any problems related to the statistics module.

13.1. Statistics Module DDS Layer

This section explains the extended DDS API provided for the Statistics Module. First, the Statistics Topic List is presented together with the corresponding collected data. Next, the methods to enable/disable the corresponding DataWriters are explained. Then, the recommended QoS for enabling the DataWriters and creating the user’s DataReaders that subscribe to the Statistics topics are described. Finally, a guide on how to overcome common problems when using the module are presented.

13.1.1. Statistics Topic names

Data collected by the Fast DDS Statistics module is published in one of the topics listed below. In order to simplify its use, the API provides aliases for the different statistics topics (see Topic names). The following table shows the correlation between the topic name and the corresponding alias.

Topic name

Alias

_fastdds_statistics_history2history_latency

HISTORY_LATENCY_TOPIC

_fastdds_statistics_network_latency

NETWORK_LATENCY_TOPIC

_fastdds_statistics_publication_throughput

PUBLICATION_THROUGHPUT_TOPIC

_fastdds_statistics_subscription_throughput

SUBSCRIPTION_THROUGHPUT_TOPIC

_fastdds_statistics_rtps_sent

RTPS_SENT_TOPIC

_fastdds_statistics_rtps_lost

RTPS_LOST_TOPIC

_fastdds_statistics_heartbeat_count

HEARTBEAT_COUNT_TOPIC

_fastdds_statistics_acknack_count

ACKNACK_COUNT_TOPIC

_fastdds_statistics_nackfrag_count

NACKFRAG_COUNT_TOPIC

_fastdds_statistics_gap_count

GAP_COUNT_TOPIC

_fastdds_statistics_data_count

DATA_COUNT_TOPIC

_fastdds_statistics_resent_datas

RESENT_DATAS_TOPIC

_fastdds_statistics_sample_datas

SAMPLE_DATAS_TOPIC

_fastdds_statistics_pdp_packets

PDP_PACKETS_TOPIC

_fastdds_statistics_edp_packets

EDP_PACKETS_TOPIC

_fastdds_statistics_discovered_entity

DISCOVERY_TOPIC

_fastdds_statistics_physical_data

PHYSICAL_DATA_TOPIC

13.1.1.1. HISTORY_LATENCY_TOPIC

The _fastdds_statistics_history2history_latency statistics topic collects data related with the latency between any two matched endpoints. This measurement provides information about the DDS overall latency independent of the user’s application overhead. Specifically, the measured latency corresponds to the time spent between the instant when the sample is written to the DataWriter’s history and the time when the sample is added to the DataReader’s history and the notification is issued to the corresponding user’s callback.

13.1.1.2. NETWORK_LATENCY_TOPIC

The _fastdds_statistics_network_latency statistics topic collects data related with the network latency (expressed in ns) between any two communicating locators. This measurement provides information about the transport layer latency. The measured latency corresponds to the time spent between the message being written until the message being received in the MessageReceiver.

Important

In the case of TCP Transport, the reported latency also includes the time spent on the datagram’s CRC related operations. Mind that is possible to disable CRC operations when defining the TCPTransportDescriptor.

13.1.1.3. PUBLICATION_THROUGHPUT_TOPIC

The _fastdds_statistics_publication_throughput statistics topic collects the amount of data (expressed in B/s) that is being sent by each DataWriter. This measurement provides information about the publication’s throughput.

13.1.1.4. SUBSCRIPTION_THROUGHPUT_TOPIC

The _fastdds_statistics_subscription_throughput statistics topic collects the amount of data (expressed in B/s) that is being received by each DataReader. This measurement provides information about the subscription’s throughput.

13.1.1.5. RTPS_SENT_TOPIC

The _fastdds_statistics_rtps_sent statistics topic collects the number of RTPS packets and bytes that are being sent from each DDS entity to each locator.

13.1.1.6. RTPS_LOST_TOPIC

The _fastdds_statistics_rtps_lost statistics topic collects the number of RTPS packets and bytes that are being lost in the transport layer (dropped somewhere in between) in the communication between each DDS entity and locator.

13.1.1.7. HEARTBEAT_COUNT_TOPIC

The _fastdds_statistics_heartbeat_count statistics topic collects the number of heartbeat messages sent by each user’s DataWriter. This topic does not apply to builtin (related to Discovery) and statistics DataWriters. Heartbeat messages are only sent if the ReliabilityQosPolicy is set to RELIABLE_RELIABILITY_QOS. These messages report the DataWriter’s status.

13.1.1.8. ACKNACK_COUNT_TOPIC

The _fastdds_statistics_acknack_count statistics topic collects the number of acknack messages sent by each user’s DataReader. This topic does not apply to builtin DataReaders (related to Discovery). Acknack messages are only sent if the ReliabilityQosPolicy is set to RELIABLE_RELIABILITY_QOS. These messages report the DataReader’s status.

13.1.1.9. NACKFRAG_COUNT_TOPIC

The _fastdds_statistics_nackfrag_count statistics topic collects the number of nackfrag messages sent by each user’s DataReader. This topic does not apply to builtin DataReaders (related to Discovery). Nackfrag messages are only sent if the ReliabilityQosPolicy is set to RELIABLE_RELIABILITY_QOS. These messages report the data fragments that have not been received yet by the DataReader.

13.1.1.10. GAP_COUNT_TOPIC

The _fastdds_statistics_gap_count statistics topic collects the number of gap messages sent by each user’s DataWriter. This topic does not apply to builtin (related to Discovery) and statistics DataWriters. Gap messages are only sent if the ReliabilityQosPolicy is set to RELIABLE_RELIABILITY_QOS. These messages report that some specific samples are not relevant to a specific DataReader.

13.1.1.11. DATA_COUNT_TOPIC

The _fastdds_statistics_data_count statistics topic collects the total number of user’s data messages and data fragments (in case that the message size is large enough to require RTPS fragmentation) that have been sent by each user’s DataWriter. This topic does not apply to builtin (related to Discovery) and statistics DataWriters.

13.1.1.12. RESENT_DATAS_TOPIC

The _fastdds_statistics_resent_data statistics topic collects the total number of user’s data messages and data fragments (in case that the message size is large enough to require RTPS fragmentation) that have been necessary to resend by each user’s DataWriter. This topic does not apply to builtin (related to Discovery) and statistics DataWriters.

13.1.1.13. SAMPLE_DATAS_TOPIC

The _fastdds_statistics_sample_datas statistics topic collects the number of user’s data messages (or data fragments in case that the message size is large enough to require RTPS fragmentation) that have been sent by the user’s DataWriter to completely deliver a single sample. This topic does not apply to builtin (related to Discovery) and statistics DataWriters.

13.1.1.14. PDP_PACKETS_TOPIC

The _fastdds_statistics_pdp_packets statistics topic collects the number of PDP discovery traffic RTPS packets transmitted by each DDS DomainParticipant. PDP packets are the data messages exchanged during the PDP discovery phase (see Discovery phases for more information).

13.1.1.15. EDP_PACKETS_TOPIC

The _fastdds_statistics_edp_packets statistics topic collects the number of EDP discovery traffic RTPS packets transmitted by each DDS DomainParticipant. EDP packets are the data messages exchanged during the EDP discovery phase (see Discovery phases for more information).

13.1.1.16. DISCOVERY_TOPIC

The _fastdds_statistics_discovered_entity statistics topic reports the time when each local DomainParticipant discovers any remote DDS entity (with the exception of those DDS entities related with the Fast DDS Statistics module). This topic also carries the PHYSICAL_DATA_TOPIC information for the case of discovered DomainParticipant; if the discovered entity is either a DataReader or DataWriter, then the physical information is empty (see Physical Data in Discovery Information for more information about how to configure the physical data conveyed on the discovery messages).

13.1.1.17. PHYSICAL_DATA_TOPIC

The _fastdds_statistics_physical_data statistics topic reports the host, user and process where the Fast DDS Statistics module is running.

13.1.2. Statistics Domain Participant

In order to start collecting data in one of the statistics topics (Statistics Topic names), the corresponding statistics DataWriter should be enabled. In fact, Fast DDS Statistics module can be enabled and disabled at runtime. For this purpose, Fast DDS Statistics module exposes an extended DDS DomainParticipant API:

13.1.2.1. Enable statistics DataWriters

Statistics DataWriters can be enabled in different ways. It can be done automatically (see Automatically enabling statistics DataWriters). Alternatively, Statistics DataWriters can be enabled at run time using one of two methods: enable_statistics_datawriter() or enable_statistics_datawriter_with_profile().

enable_statistics_datawriter() method requires as parameters:

It is possible to define specific desired QoS through DataWriter profile on the FASTDDS_DEFAULT_PROFILES_FILE (see XML profiles). enable_statistics_datawriter_with_profile() method enables a DataWriter by searching a specific DataWriter XML profile. On those profiles, specific QoS can be set.

enable_statistics_datawriter_with_profile() method requires as parameters:

  • Name of the XML profile to use to fill the QoS structure of the DataWriter.

  • Name of the statistics topic name to be enabled. (see Statistics Topic names for the statistics topic list).

13.1.2.2. Disable statistics DataWriters

Statistics DataWriters are disabled using the method disable_statistics_datawriter(). This method requires as parameter:

13.1.2.3. Obtain pointer to the extended DomainParticipant class

The DomainParticipant is created using the create_participant() provided by the DomainParticipantFactory. This method returns a pointer to the DDS standard DomainParticipant created. In order to obtain the pointer to the child DomainParticipant which extends the DDS API, the static method narrow() is provided.

13.1.2.4. Example

The following example shows how to use the Statistics module extended DDS API:

// Create a DomainParticipant
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Obtain pointer to child class
eprosima::fastdds::statistics::dds::DomainParticipant* statistics_participant =
        eprosima::fastdds::statistics::dds::DomainParticipant::narrow(participant);

// Enable statistics DataWriter
if (statistics_participant->enable_statistics_datawriter(eprosima::fastdds::statistics::GAP_COUNT_TOPIC,
        eprosima::fastdds::statistics::dds::STATISTICS_DATAWRITER_QOS) != RETCODE_OK)
{
    // Error
    return;
}

// Use the DomainParticipant to communicate
// (...)

// Disable statistics DataWriter
if (statistics_participant->disable_statistics_datawriter(eprosima::fastdds::statistics::GAP_COUNT_TOPIC) !=
        RETCODE_OK)
{
    // Error
    return;
}

// Delete DomainParticipant
if (DomainParticipantFactory::get_instance()->delete_participant(participant) != RETCODE_OK)
{
    // Error
    return;
}
13.1.2.5. Automatically enabling statistics DataWriters

The statistics DataWriters can be directly enabled using the DomainParticipantQos properties() fastdds.statistics. The value of this property is a semicolon separated list containing the statistics topic name aliases of those DataWriters that the user wants to enable. The property can be set either programmatically or loading an XML file. If the property is set in both ways, the priority would depend on the API and the QoS profile provided:

Another way of enabling statistics DataWriters, compatible with the previous one, is setting the FASTDDS_STATISTICS environment variable. The statistics DataWriters that will be enabled when the DomainParticipant is enabled would be the union between those specified in the properties() fastdds.statistics and those included with the environment variable.

The following examples show how to use all the previous methods:

DomainParticipantQos pqos;

// Activate Fast DDS Statistics module
pqos.properties().properties().emplace_back("fastdds.statistics",
        "HISTORY_LATENCY_TOPIC;ACKNACK_COUNT_TOPIC;DISCOVERY_TOPIC;PHYSICAL_DATA_TOPIC");
<participant profile_name="statistics_domainparticipant_conf_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Activate Fast DDS Statistics Module -->
                <property>
                    <name>fastdds.statistics</name>
                    <value>HISTORY_LATENCY_TOPIC;ACKNACK_COUNT_TOPIC;DISCOVERY_TOPIC;PHYSICAL_DATA_TOPIC</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>
export FASTDDS_STATISTICS="HISTORY_LATENCY_TOPIC;ACKNACK_COUNT_TOPIC;DISCOVERY_TOPIC;PHYSICAL_DATA_TOPIC"
set FASTDDS_STATISTICS=HISTORY_LATENCY_TOPIC;ACKNACK_COUNT_TOPIC;DISCOVERY_TOPIC;PHYSICAL_DATA_TOPIC

Note

These are all the statistics topics:

HISTORY_LATENCY_TOPIC;NETWORK_LATENCY_TOPIC;PUBLICATION_THROUGHPUT_TOPIC;SUBSCRIPTION_THROUGHPUT_TOPIC;RTPS_SENT_TOPIC;RTPS_LOST_TOPIC;HEARTBEAT_COUNT_TOPIC;ACKNACK_COUNT_TOPIC;NACKFRAG_COUNT_TOPIC;GAP_COUNT_TOPIC;DATA_COUNT_TOPIC;RESENT_DATAS_TOPIC;SAMPLE_DATAS_TOPIC;PDP_PACKETS_TOPIC;EDP_PACKETS_TOPIC;DISCOVERY_TOPIC;PHYSICAL_DATA_TOPIC

Note

Be aware that automatically enabling the statistics DataWriters using all these methods implies using the recommended QoS profile STATISTICS_DATAWRITER_QOS. For more information, please refer to Statistics DataWriter recommended QoS. However, if an XML profile is defined, the QoS applied are those defined in the profile, and for those QoS that are not specified in that profile, the default library QoS are applied (see DataWriterQos for the standard eProsima’s DataWriter QoS), and not the recommended QoS for the Statistics DataWriters.

For the creation of an automatically enabled Datawriter, the priority for setting its QoS is the following:

  • First, if a specific profile exists for the statistics topic, that one is applied.

  • If that is not the case but a generic profile for statistics DataWriters exists, that one is applied.

  • If no profile is defined in XML file, the recommended statistics QoS are applied.

Note

The generic DataWriter profile defined in the FASTDDS_DEFAULT_PROFILES_FILE XML needs to be named as GENERIC_STATISTICS_PROFILE.

The specific DataWriter profile defined in the FASTDDS_DEFAULT_PROFILES_FILE XML needs to be named using the same statistic topic alias or name (see Statistics Topic names for the alias corresponding to each statistic topic) that has been used in the DomainParticipantQos properties() fastdds.statistics (see Statistics Module Settings) or the FASTDDS_STATISTICS environment variable, where the enabling of the corresponding statistics topic has been set.

13.1.4. Troubleshooting

This section aims to give quick solutions to overcome the most common problems arising from the use of the statistics module.

13.1.4.1. Monitoring application is not receiving any statistic data

Sometimes, especially in the case of monitoring large applications with many DataWriters and DataReaders, it may happen that the application monitoring Fast DDS statistics does not receive any data. This is generally caused by the default configuration of the statistics DataWriters, which includes the push_mode set to false (i.e. pull_mode), the History Kind set to KEEP_LAST, and the History Depth set to 10. With this configuration, the following may happen:

  1. Fast DDS adds new samples to one of the statistics DataWriters.

  2. The DataWriter notifies the DataReader of the availability of said samples.

  3. The DataReader sends a request to the DataWriter to “pull” those samples.

  4. Before the request arrives to the DataWriter, some new statistics samples are added to that same DataWriter, which causes the previous samples to be overwritten.

  5. Once the DataReader request arrives to the DataWriter, since the requested samples have been overwritten, they are not available any more, so the DataWriter send a notification to the DataReader informing of the presence of the newer samples instead.

  6. The loop starts again.

The easiest fix to overcome this situation is to simply increase the History Depth of the DataWriter to create Some buffer to answer to requests:

<?xml version="1.0" encoding="utf-8"?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="statistics_domainparticipant_conf_xml_general_profile">
            <rtps>
                <propertiesPolicy>
                    <properties>
                        <!-- Activate various Fast DDS Statistics Module DataWriters -->
                        <property>
                            <name>fastdds.statistics</name>
                            <value>HISTORY_LATENCY_TOPIC;DISCOVERY_TOPIC;PHYSICAL_DATA_TOPIC</value>
                        </property>
                    </properties>
                </propertiesPolicy>
            </rtps>
        </participant>

        <!-- Generic profile for all the statistics DataWriter -->
        <data_writer profile_name="GENERIC_STATISTICS_PROFILE">
            <!-- Configure History QoS as KEEP_LAST 20 -->
            <!-- History depth depends on the user application constraints (publication rate for instance) -->
            <topic>
                <historyQos>
                    <kind>KEEP_LAST</kind>
                    <depth>20</depth>
                </historyQos>
            </topic>
            <!-- Enable pull mode -->
            <propertiesPolicy>
                <properties>
                    <property>
                        <name>fastdds.push_mode</name>
                        <value>false</value>
                    </property>
                </properties>
            </propertiesPolicy>
            <!-- Set durability, reliability, and publication mode -->
            <qos>
                <durability>
                    <kind>TRANSIENT_LOCAL</kind>
                </durability>

                <reliability>
                    <kind>RELIABLE</kind>
                </reliability>

                <publishMode>
                    <kind>ASYNCHRONOUS</kind>
                </publishMode>
            </qos>
        </data_writer>
    </profiles>
</dds>
<?xml version="1.0" encoding="utf-8"?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <participant profile_name="statistics_domainparticipant_conf_xml_specific_profile">
            <rtps>
                <propertiesPolicy>
                    <properties>
                        <!-- Activate various Fast DDS Statistics Module DataWriters -->
                        <property>
                            <name>fastdds.statistics</name>
                            <value>HISTORY_LATENCY_TOPIC</value>
                        </property>
                    </properties>
                </propertiesPolicy>
            </rtps>
        </participant>

        <!-- Generic profile for a specific statistics DataWriters -->
        <data_writer profile_name="HISTORY_LATENCY_TOPIC">
            <!-- Configure History QoS as KEEP_LAST 20 -->
            <!-- History depth depends on the user application constraints (publication rate for instance) -->
            <topic>
                <historyQos>
                    <kind>KEEP_LAST</kind>
                    <depth>20</depth>
                </historyQos>
            </topic>
            <!-- Enable pull mode -->
            <propertiesPolicy>
                <properties>
                    <property>
                        <name>fastdds.push_mode</name>
                        <value>false</value>
                    </property>
                </properties>
            </propertiesPolicy>
            <!-- Set durability, reliability, and publication mode -->
            <qos>
                <durability>
                    <kind>TRANSIENT_LOCAL</kind>
                </durability>

                <reliability>
                    <kind>RELIABLE</kind>
                </reliability>

                <publishMode>
                    <kind>ASYNCHRONOUS</kind>
                </publishMode>
            </qos>
        </data_writer>
    </profiles>
</dds>

Warning

Mind that the specific profile only targets to the DataWriter which profile name matches with the alias of the corresponding statistics topic. Check the complete list of topics and their aliases in the Statistics Topic names section.

Note

Increasing the History Depth of the statistics DataWriters has an impact on memory usage, as sufficient space is pre-allocated for each of the DataWriter’s histories to hold that number of samples per topic instance.

13.2. Monitor Service

The Fast DDS Monitor Service is a feature of Fast DDS that grants the user the ability to collect data about the entities existing within a particular domain (i.e DomainParticipants, DataReaders, DataWriters) as well as the capability of detecting possible misconfigurations among them.

13.2.1. Introduction

The Monitor Service targets any application implementing the subscription side of the Monitor Service Status Topic, giving the possibility of retrieving the Monitoring Information of the local entities (incompatible QoS, deadlines missed, active connections,…).

13.2.1.1. Keywords
  • Proxy: An entity that acts on behalf of another entity.

  • Proxy Data: The way in which a Proxy can be described.

  • Monitoring Information: The collection of different sources of information and statuses of an entity, including: the Proxy Data, incompatible QoS, connections, liveliness, deadlines missed, inconsistent topics and lost sample status.

13.2.1.2. Description

Enabling the service makes each DomainParticipant publish its local entities, each one with its related Monitoring Information.

The Monitor Service is disabled by default, as it may entail a performance cost. Further information on the Monitor Service topics and how to configure it is described in the following sections.

The Monitor Service is available in both the DDS Layer and RTPS Layer.

Note

If the service is activated within a RTPS context, not all the Monitoring Information may be published by the service.

13.2.1.3. Use Cases

The Monitor Service can be particularly useful in the following scenarios:

  • Collecting the Monitoring Information of any local entity of a remote DomainParticipant in order to extend the default discovery information (see Discovery) about it.

  • Troubleshooting issues regarding discovery or entity-matching, leveraging the information of the current locators in use, for example.

  • Recreating an entity graph of a certain domain given that all participants are able to discover each other.

13.2.2. Monitor Service Topics

The following table depicts the properties of the topics within the Monitor Service:

Topic name

Topic Alias

TopicDataType

fastdds_monitor_service_status

MONITOR_SERVICE_TOPIC

Monitor Service Status Data

13.2.2.1. Monitor Service Status Topic

The Monitor Service Status Topic carries information about the monitoring information of the local entities of a particular DomainParticipant. The monitoring information can be divided into different statuses identified by a StatusKind. The possible values are described in the following table:

Value

Name

Description

0

ProxyInfo

Collection of Parameters describing the Proxy Data of that entity

1

ConnectionList

List of connections that this entity is using with its matched remote entities.

2

IncompatibleQoSInfo

Status of the Incompatible QoS of that entity.

3

InconsistentTopicInfo

Status of Inconsistent topics that the topic of that entity has.

4

LivelinessLostInfo

Tracks the status of the number of times a writer lost liveliness.

5

LivelinessChangedInfo

Tracks the status of the number of times the liveliness changed in a reader.

6

DeadlineMissedInfo

The Status of the number of deadlines missed of a sample for that entity.

7

SampleLostInfo

Tracks the status of the number of times this entity lost samples.

8

ExtendedIncompatibleQoS

Stores the list of remote incompatible GUIDs and QoS policies for each local entity guid.

Note

If the service is enabled in a RTPS layer context, not all the statuses will be published, only the ProxyInfo and ConnectionList.

The Monitor Service Status Topic publishes new data when new updates are received from any of the DomainParticipant’s local entities (on-event driven) with a minimum waiting time between publications. In addition, it is in charge of notifying about any disposal or liveliness lost.

13.2.2.1.1. Monitor Service Status Data

The MonitorServiceStatusData data structure comprises the following fields:

  • local_entity: Guid_t of the local entity.

  • status_kind: StatusKind enumeration identifying the status.

  • value: The value of the status.

MonitorServiceStatusData
  @Key GUID local_entity
  @Key StatusKind status_kind
  Data value

Note

The local_entity and status_kind are keyed fields, hence making use of instances (see Topics, keys and instances). In this case, the pair <local_entity, status_kind> identifies a unique instance.

Each of the StatusKind enumeration values maps to a corresponding Data value. The actual field names for the different values are described below:

  • entity_proxy: Collection of the serialized Quality of Service Parameters in the form of a ParameterList.

  • connection_list: Defines how is this entity communicating with its matched entities. Each of the elements is of Connection type (depicted below).

Connection
  uint32_t mode //INTRAPROCESS, DATASHARING, TRANSPORT
  LocatorList announced_locators
  LocatorList used_locators
  • incompatible_qos_status: Status of the Incompatible QoS of that entity.

  • inconsistent_topic_status: Status of Inconsistent topics of the topic of that entity. Asked to the topic of the requested entity.

  • liveliness_lost_status: Tracks the status of the number of times that liveliness was lost by a DataWriter.

  • liveliness_changed_status: Tracks the status of the number of times that liveliness was lost by a DataReader.

  • deadline_status: The Status of the number of deadlines missed that were registered in that entity.

  • sample_lost_status: The number of samples that entity lost.

  • extended_incompatible_qos_status: Details a list of remote GUIDs with incompatible QoS with a local entity and the particular QosPolicyId_t of those incompatible policies.

ExtendedIncompatibleQoSStatus_s
  GUID remote_guid
  sequence<unsigned long> current_incompatible_policies

ExtendedIncompatibleQoSStatusSeq = sequence<ExtendedIncompatibleQoSStatus>

The following table depicts the relation between each of the StatusKind values and the Data field:

StatusKind

StatusKind Name

Data field Name

IDL Data field Type

0

ProxyInfo

entity_proxy

sequence<octet>

1

ConnectionList

connection_list

sequence<Connection>

2

IncompatibleQoSInfo

incompatible_qos_status

IncompatibleQoSStatus

3

InconsistentTopicInfo

inconsistent_topic_status

InconsistentTopicStatus

4

LivelinessLostInfo

liveliness_lost_status

LivelinessLostStatus

5

LivelinessLostInfo

liveliness_changed_status

LivelinessChangedStatus

6

DeadlineMissedInfo

deadline_missed_status

DeadlineMissedStatus

7

SampleLostInfo

sample_lost_status

SampleLostStatus

8

ExtendedIncompatibleQoS

extended_incompatible_qos_status

ExtendedIncompatibleQoSStatusSeq

13.2.3. Monitor Service Configuration

The Monitor Service can be activated using the -DFASTDDS_STATISTICS=ON at CMake configuration step (for further information regarding the Fast DDS compilation, see Linux installation from sources and Windows installation from sources). Once the Monitor Service feature is activated, it can be programmatically enabled in both DDS Layer and RTPS Layer through the enable_monitor_service() and disable_monitor_service() calls. In addition, leveraging the PropertyPolicyQos there is new Property defined for the purpose: fastdds.enable_monitor_service.

The following table depicts the different ways in which the Monitor Service can be enabled or disabled:

DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0,
                PARTICIPANT_QOS_DEFAULT);

// Obtain pointer to child class
eprosima::fastdds::statistics::dds::DomainParticipant* statistics_participant =
        eprosima::fastdds::statistics::dds::DomainParticipant::narrow(participant);


// Enable Fast DDS Monitor Service through API
statistics_participant->enable_monitor_service();

// Disable Fast DDS Monitor Service through API
statistics_participant->disable_monitor_service();
DomainParticipantQos pqos;

// Enable Fast DDS Monitor Service through properties
pqos.properties().properties().emplace_back("fastdds.enable_monitor_service",
        "true");

// Enable Fast DDS Monitor Service through statistics properties (other way)
pqos.properties().properties().emplace_back("fastdds.statistics",
        "MONITOR_SERVICE_TOPIC");

DomainParticipant* participant_with_mon_srv = DomainParticipantFactory::get_instance()->create_participant(0,
                pqos);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
<participant profile_name="monitor_service_participant_xml_profile">
    <rtps>
        <propertiesPolicy>
            <properties>
                <!-- Enable Monitor Service -->
                <property>
                    <name>fastdds.enable_monitor_service</name>
                    <value>true</value>
                </property>
                <!-- Include Monitor Service in the Fast DDS Statistics (other way to enable it) -->
                <property>
                    <name>fastdds.statistics</name>
                    <value>MONITOR_SERVICE_TOPIC</value>
                </property>
            </properties>
        </propertiesPolicy>
    </rtps>
</participant>
</profiles>
export FASTDDS_STATISTICS="MONITOR_SERVICE_TOPIC"
set FASTDDS_STATISTICS=MONITOR_SERVICE_TOPIC
13.2.3.1. Endpoints QoS

For any consumer application of the Monitor Service, the following endpoint QoS of the Monitor Service Status Topic DataWriter should be taken into consideration:

14. XTypes

eProsima Fast DDS supports the OMG Extensible and Dynamic Topic Types for DDS specification (also known as XTypes). This specification defines the following concepts:

  • DDS supported type system, including the concept of extensible types that might evolve in time.

  • Type representation, including IDL and TypeObject representations.

  • Data representation over the wire.

  • Language binding, defining both a plain and a dynamic language binding. eProsima Fast DDS-Gen generates the plain language binding given an IDL type representation. Dynamic Language Binding section explains the required API to define and set/read the data types.

  • DDS builtin mechanism to automatically discover remote data types. More information in Remote Data Types Discovery section.

14.1. Remote Data Types Discovery

DDS-XTypes specification defines an internal mechanism to discover the remote data types at runtime and match depending on the extensible types compatibility rules configured using the TypeConsistencyEnforcementQosPolicy.

Note

eProsima Fast DDS does not support XTypes compatibility check yet.

The remote data type discovery mechanism is based on the exchange of the data type information optimized in order to reduce the required bandwidth. On the one hand, TypeInformation structure defined in the IDL below (extracted from Annex B of the DDS-XTypes specification), is used to communicate the Topic Data Type and its dependencies.

@extensibility(APPENDABLE) @nested
struct TypeIdentfierWithSize
{
    TypeIdentifier      type_id;
    unsigned long       typeobject_serialized_size;
};

@extensibility(APPENDABLE) @nested
struct TypeIdentifierWithDependencies
{
    TypeIdentfierWithSize           typeid_with_size;
    long                            dependent_type_id_count;
    sequence<TypeIdentfierWithSize> dependent_typeids;
};

@extensibility(MUTABLE) @nested
struct TypeInformation
{
    @id(0x1001) TypeIdentifierWithDependencies minimal;
    @id(0x1002) TypeIdentifierWithDependencies complete;
};

TypeInformation includes the TypeIdentifier, the data type information hashed which identifies almost univocally the data type. The data type information is contained in the TypeObject union:

@extensibility(APPENDABLE) @nested
union TypeObject switch(octet)
{
    case EK_COMPLETE:
        CompleteTypeObject  complete;
    case EK_MINIMAL:
        MinimalTypeObject   minimal;
};

The CompleteTypeObject includes the data type full description. On the other hand, MinimalTypeObject only includes the minimum required information in order to check type compatibility.

Important

Current TypeObject representation implementation does not support forward declarations or recursive data types defined using the @external annotation. Please, remember to disable TypeObject generation code using -no-typeobjectsupport option when generating the code using Fast DDS-Gen.

14.1.1. Prerequisites

The remote data type discovery feature only works if some requisites are met:

  1. The local data types must be registered into the ITypeObjectRegistry. The types are automatically registered when calling register_type() / register_type() if the code required for registration has been generated using eProsima Fast DDS-Gen. Fast DDS-Gen generates the required files (<IDLFileName>TypeObjectSupport.cxx/.hpp) by default.

    Note

    -no-typeobjectsupport option disables the generation of these files and effectively disables the discovery of remote types.

  2. TypeInformation should be received with the DomainParticipant’s endpoint discovery information. A DomainParticipant that does not inform about its TypeInformation would not trigger the remote data type discovery mechanism.

If the prerequisites are not met, endpoint matching relies on type name and topic name in order to match the discovered endpoints.

14.1.2. Configuration

The level of propagation of local data types can be configured as specified in Type Propagation.

14.1.3. Remote types discovery example

Please, refer to Remote type discovery and endpoint matching for more information about how to leverage this feature.

14.2. Dynamic Language Binding

The Dynamic Language Binding API allows to define data types at runtime instead of having the types predefined as it is required by the Plain Language Binding. This API includes both the type definition and, the getters and setters required to use the defined types. Type definition can also be done using a XML configuration file as explained in Dynamic Types profiles section or by parsing an IDL file at runtime, as explained in Dynamic Types IDL Parsing section.

This section presents first the Dynamic Language Binding API, and then the supported types and specific examples defining and using those types.

14.2.1. Dynamic Language Binding Interfaces

This section briefly presents the Dynamic Language Binding API. For more information, please refer both to the DDS-XTypes specification and the API reference.

14.2.1.1. TypeDescriptor

TypeDescriptor is in charge of describing the state of a type. Objects of this interface have value semantics allowing the TypeDescriptor data to be deeply copied and compared.

14.2.1.2. AnnotationDescriptor

AnnotationDescriptor is in charge of describing the user-defined applied annotation to a specific element. Objects of this interface have value semantics allowing the AnnotationDescriptor data to be deeply copied and compared.

14.2.1.3. MemberDescriptor

MemberDescriptor is in charge of describing the state of a specific member of a type. Objects of this interface have value semantics allowing the MemberDescriptor data to be deeply copied and compared.

14.2.1.4. VerbatimTextDescriptor

VerbatimTextDescriptor is in charge of describing the @verbatim builtin annotation application. Objects of this interface have value semantics allowing the VerbatimTextDescriptor data to be deeply copied and compared.

14.2.1.5. DynamicTypeBuilderFactory

The DynamicTypeBuilderFactory serves as a singleton which instance is responsible for both creating and deleting DynamicTypeBuilder objects. This class provides the generic DynamicTypeBuilderFactory::create_type API, and also specific APIs to define other basic types such as strings, sequences, etc. More information can be found in Supported Types section.

14.2.1.6. DynamicType

DynamicType objects represents a specific type definition. Once the DynamicType has been built, it cannot be modified. Objects of this interface have reference semantics, so the API receives a nil-reference which is then returned pointing to the correct DynamicType address.

14.2.1.7. DynamicTypeMember

DynamicTypeMember represents a data member of a DynamicType. Objects of this interface have reference semantics, so the API receives a nil-reference which is then returned pointing to the correct DynamicTypeMember address.

14.2.1.8. DynamicTypeBuilder

DynamicTypeBuilder interface allows the instantiation of concrete DynamicType objects and serves as a transitional state for configuring the DynamicType before its creation. Upon definition, DynamicTypeBuilderFactory leverages the information contained in the builder to create the DynamicType. DynamicTypeBuilder::build allows for creating the fully constructed DynamicType. Builders remain reusable after DynamicType creation, ensuring changes to the builder do not affect previously created types.

14.2.1.9. DynamicDataFactory

DynamicDataFactory serves as a singleton which instance is responsible for both creating and deleting DynamicData objects from a given DynamicType instance.

14.2.1.10. DynamicData

DynamicData represents a data instance of a DynamicType, providing functionalities to access and modify data values. Each DynamicData object corresponds to an object of the type represented by its DynamicType. Offering reflective getters and setters, DynamicData enables manipulation of individual data samples.

14.2.2. Supported Types

This section describes the supported Type System including examples of how to instantiate those specific types using the Dynamic Language Binding API and the XML configuration file. The C++ examples also include instantiating the corresponding DynamicData sample, and setting and reading a value.

14.2.2.1. Primitive Types

Primitive types are self-describing and can be created without configuration parameters. The DynamicTypeBuilderFactory interface exposes the method DynamicTypeBuilderFactory::get_primitive_type to allow users to directly get the corresponding primitive DynamicType. The DynamicData class provides specific getters and setters for each primitive data type.

The following table shows the supported primitive types and their corresponding TypeKind. The TypeKind is used to query the DynamicTypeBuilderFactory for the specific primitive DynamicType.

C++ Type

TypeKind

bool

TK_BOOLEAN

char

TK_CHAR8

wchar_t

TK_CHAR16

uint8_t

TK_BYTE / TK_UINT8

int8_t

TK_INT8

int16_t

TK_INT16

uint16_t

TK_UINT16

int32_t

TK_INT32

uint32_t

TK_UINT32

int64_t

TK_INT64

uint64_t

TK_UINT64

float

TK_FLOAT32

double

TK_FLOAT64

long double

TK_FLOAT128

The example below shows how to create an structure with primitive members.

struct PrimitivesStruct
{
    boolean my_bool;
    octet my_octet;
    char my_char;
    wchar my_wchar;
    long my_long;
    unsigned long my_ulong;
    int8 my_int8;
    uint8 my_uint8;
    short my_short;
    unsigned short my_ushort;
    long long my_longlong;
    unsigned long long my_ulonglong;
    float my_float;
    double my_double;
    long double my_longdouble;
};
<struct name="PrimitivesStruct">
    <member name="my_bool" type="boolean"/>
    <member name="my_octet" type="byte"/>
    <member name="my_char" type="char8"/>
    <member name="my_wchar" type="char16"/>
    <member name="my_long" type="int32"/>
    <member name="my_ulong" type="uint32"/>
    <member name="my_int8" type="int8"/>
    <member name="my_uint8" type="uint8"/>
    <member name="my_short" type="int16"/>
    <member name="my_ushort" type="uint16"/>
    <member name="my_longlong" type="int64"/>
    <member name="my_ulonglong" type="uint64"/>
    <member name="my_float" type="float32"/>
    <member name="my_double" type="float64"/>
    <member name="my_longdouble" type="float128"/>
</struct>
// Define a struct type with various primitive members
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("PrimitivesStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(type_descriptor)};

// Define and add primitive members to the struct
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
member_descriptor->name("my_bool");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_BOOLEAN));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_octet");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_BYTE));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_char");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_CHAR8));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_wchar");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_CHAR16));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_long");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT32));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_ulong");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_UINT32));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_int8");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT8));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_uint8");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_UINT8));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_short");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT16));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_ushort");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_UINT16));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_longlong");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT64));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_ulonglong");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_UINT64));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_float");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_FLOAT32));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_double");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_FLOAT64));
struct_builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_longdouble");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_FLOAT128));
struct_builder->add_member(member_descriptor);

// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};

// Set and retrieve values for a member of type int32_t
int32_t in_value {2};
int32_t out_value {0};
data->set_int32_value(data->get_member_id_by_name("my_long"), in_value);
data->get_int32_value(out_value, data->get_member_id_by_name("my_long"));

For a detailed explanation about the XML definition of this type, please refer to XML Primitive Types.

14.2.2.1.1. Type promotions

The Dynamic Language Binding also supports type promotion, enabling implicit promotion of types during both get() and set() operations. This means that a smaller type can be implicitly promoted to a larger type, but not the other way around.

The following promotions are supported:

TypeKind

Allowed promotions

TK_INT8

TK_INT16, TK_INT32, TK_INT64, TK_FLOAT32, TK_FLOAT64, TK_FLOAT128

TK_INT16

TK_INT32, TK_INT64, TK_FLOAT32, TK_FLOAT64, TK_FLOAT128

TK_INT32

TK_INT64, TK_FLOAT64, TK_FLOAT128

TK_INT64

TK_FLOAT128

TK_UINT8

TK_INT16, TK_INT32, TK_INT64, TK_UINT16, TK_UINT32, TK_UINT64, TK_FLOAT32, TK_FLOAT64, TK_FLOAT128

TK_UINT16

TK_INT32, TK_INT64, TK_UINT32, TK_UINT64, TK_FLOAT32, TK_FLOAT64, TK_FLOAT128

TK_UINT32

TK_INT64, TK_UINT64, TK_FLOAT64, TK_FLOAT128

TK_UINT64

TK_FLOAT128

TK_FLOAT32

TK_FLOAT64, TK_FLOAT128

TK_FLOAT64

TK_FLOAT128

TK_FLOAT128

(none)

TK_CHAR8

TK_CHAR16, TK_INT16, TK_INT32, TK_INT64, TK_FLOAT32, TK_FLOAT64, TK_FLOAT128

TK_CHAR16

TK_INT32, TK_INT64, TK_FLOAT32, TK_FLOAT64, TK_FLOAT128

TK_BYTE

(any)

TK_BOOLEAN

TK_INT8, TK_INT16, TK_INT32, TK_INT64, TK_UINT8, TK_UINT16, TK_UINT32, TK_UINT64, TK_FLOAT32, TK_FLOAT64, TK_FLOAT128

14.2.2.2. String Types

String types are one-dimensional collections of characters (TK_CHAR8 or TK_CHAR16. The latest are also known as wide strings or wstring). The TypeKinds used to identify string types are TK_STRING8 and TK_STRING16. The string may be bounded, setting a maximum length, or unbounded. This is configured using TypeDescriptor bound property.

DynamicTypeBuilderFactory exposes the functions DynamicTypeBuilderFactory::create_string_type and DynamicTypeBuilderFactory::create_wstring_type that eases string creation providing the corresponding maximum length parameter (LENGTH_UNLIMITED is used for unbounded strings).

DynamicData class provides also with specific getters and setters: DynamicData::get_string_value, DynamicData::get_wstring_value, DynamicData::set_string_value, and DynamicData::set_wstring_value.

struct StringsStruct
{
    string my_string;
    wstring my_wstring;
    string<41925> my_bounded_string;
    wstring<20925> my_bounded_wstring;
};
<struct name="StringsStruct">
    <member name="my_string" type="string"/>
    <member name="my_wstring" type="wstring"/>
    <member name="my_bounded_string" type="string" stringMaxLength="41925"/>
    <member name="my_bounded_wstring" type="wstring" stringMaxLength="20925"/>
</struct>
// Define a struct type to contain the strings
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("StringsStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(type_descriptor)};

// Define and add string members to the struct
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};

member_descriptor->name("my_string");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                create_string_type(static_cast<uint32_t>(LENGTH_UNLIMITED))->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_STRING8);
    type_descriptor->element_type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_CHAR8));
    type_descriptor->bound().push_back(static_cast<uint32_t>(LENGTH_UNLIMITED));
    member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(type_descriptor)->build());
 */

struct_builder->add_member(member_descriptor);
member_descriptor->name("my_wstring");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                create_wstring_type(static_cast<uint32_t>(LENGTH_UNLIMITED))->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_STRING16);
    type_descriptor->element_type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_CHAR16));
    type_descriptor->bound().push_back(static_cast<uint32_t>(LENGTH_UNLIMITED));
    member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(type_descriptor)->build());
 */

struct_builder->add_member(member_descriptor);
member_descriptor->name("my_bounded_string");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                create_string_type(41925)->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_STRING8);
    type_descriptor->element_type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_CHAR8));
    type_descriptor->bound().push_back(41925);
    member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(type_descriptor)->build());
 */

struct_builder->add_member(member_descriptor);
member_descriptor->name("my_bounded_wstring");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                create_wstring_type(20925)->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_STRING16);
    type_descriptor->element_type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_CHAR16));
    type_descriptor->bound().push_back(20925);
    member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(type_descriptor)->build());
 */

struct_builder->add_member(member_descriptor);

// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};

// Set and retrieve values for a string member
std::string in_value {"helloworld"};
std::string out_value;
data->set_string_value(data->get_member_id_by_name("my_string"), in_value);
data->get_string_value(out_value, data->get_member_id_by_name("my_string"));

For a detailed explanation about the XML definition of this type, please refer to XML String Types.

14.2.2.3. Enumeration Types

An enumeration contains a set of supported values (enumeration literals) and a selected value among those supported. The TypeKind used to identify enumeration types is TK_ENUM.

The enumeration literals must be configured using the DynamicTypeBuilder by calling the DynamicTypeBuilder::add_member function for the respective supported values. The MemberDescriptor passed to the previous function must determine the enumeration literal name by using name property. The underlying primitive type related to the enumeration is configured using MemberDescriptor type property. This primitive type is determined when adding the first enumeration literal. For the enumeration type to be consistent, the remaining enumeration literals must be of the same primitive type. Additionally, the enumeration literal value might be set using MemberDescriptor default_value property. The behavior is the same as setting the @value builtin annotation.

As the enumeration type is basically a signed integer type which might take only some specific values defined with the enumeration literals, the corresponding DynamicData getters and setters are the ones corresponding to the underlying signed integer type (and any other method promotable to that specific primitive type).

enum MyEnum
{
    A,
    B,
    C
};

struct EnumStruct
{
    MyEnum my_enum;
};
<enum name="MyEnum">
    <enumerator name="A" value="0"/>
    <enumerator name="B" value="1"/>
    <enumerator name="C"/>
</enum>

<struct name="EnumStruct">
    <member name="my_enum" type="nonBasic" nonBasicTypeName="MyEnum"/>
</struct>
enum MyEnum : int32_t
{
    A,
    B,
    C
};

// Define a struct type to contain an enum
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("EnumStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(type_descriptor)};
// Define the enum type
TypeDescriptor::_ref_type enum_type_descriptor {traits<TypeDescriptor>::make_shared()};
enum_type_descriptor->kind(TK_ENUM);
enum_type_descriptor->name("MyEnum");
DynamicTypeBuilder::_ref_type enum_builder {DynamicTypeBuilderFactory::get_instance()->
                                                    create_type(enum_type_descriptor)};
// Add enum literals to the enum type
MemberDescriptor::_ref_type enum_member_descriptor {traits<MemberDescriptor>::make_shared()};
enum_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT32));
enum_member_descriptor->name("A");
enum_builder->add_member(enum_member_descriptor);
enum_member_descriptor = traits<MemberDescriptor>::make_shared();
enum_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT32));
enum_member_descriptor->name("B");
enum_builder->add_member(enum_member_descriptor);
enum_member_descriptor = traits<MemberDescriptor>::make_shared();
enum_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT32));
enum_member_descriptor->name("C");
enum_builder->add_member(enum_member_descriptor);
// Build the enum type
DynamicType::_ref_type enum_type = enum_builder->build();

// Add an enum member to the struct
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
member_descriptor->name("my_enum");
member_descriptor->type(enum_type);
struct_builder->add_member(member_descriptor);
// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};

// Set and retrieve values for an enum member
MyEnum in_value {MyEnum::C};

/* Alternative
    uint32_t in_value {2}; // Selecting MyEnum::C
 */

uint32_t out_value {0};
data->set_uint32_value(data->get_member_id_by_name("my_enum"), in_value);
data->get_uint32_value(out_value, data->get_member_id_by_name("my_enum"));

For a detailed explanation about the XML definition of this type, please refer to XML Enumeration Types.

14.2.2.4. Bitmask Types

Bitmask types are a collection of boolean flags (bitflags) that can be set individually. The TypeKind used to identify bitmask types is TK_BITMASK. The bitmasks bound, maximum number of bits, must be set using the TypeDescriptor bound property. The maximum bound allowed is 64 bits.

The bitflags must be configured using the DynamicTypeBuilder by calling the DynamicTypeBuilder::add_member function. Each bitflag is described using a MemberDescriptor defining the bitflag name using the name property. The underlying primitive type related to bitflags must be of kind TK_BOOLEAN and must be set in MemberDescriptor type property. The MemberDescriptor id property might be used to indicate the bitflag position within the bitmask. This behavior is the same as setting the @position builtin annotation. If the position is not specified, sequential order is followed.

The DynamicTypeBuilderFactory exposes the function DynamicTypeBuilderFactory::create_bitmask_type to facilitate the creation of bitmask types.

Bitmask types can be manipulated either using the DynamicData::get_boolean_value/DynamicData::set_boolean_value in order to set a specific bitflag, or by using the unsigned integer setter/getter corresponding to the bitmask bound. In this latest case, only bitflags are going to be set (bits not named are always unset).

@bit_bound(8)
bitmask MyBitMask
{
    @position(0) flag0,
    flag1,
    flag2,
    @position(5) flag5
};

struct BitmaskStruct
{
    MyBitMask my_bitmask;
};
<bitmask name="MyBitMask" bit_bound="8">
    <bit_value name="flag0" position="0"/>
    <bit_value name="flag1"/>
    <bit_value name="flag2"/>
    <bit_value name="flag5" position="5"/>
</bitmask>

<struct name="BitmaskStruct">
    <member name="my_bitmask" type="nonBasic" nonBasicTypeName="MyBitMask"/>
</struct>
// Define a struct type to contain a bitmask
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("BitmaskStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(type_descriptor)};

// Define the bitmask type
DynamicTypeBuilder::_ref_type bitmask_builder {DynamicTypeBuilderFactory::get_instance()->create_bitmask_type(
                                                   8)};

/* Alternative
    TypeDescriptor::_ref_type bitmask_type_descriptor {traits<TypeDescriptor>::make_shared()};
    bitmask_type_descriptor->kind(TK_BITMASK);
    bitmask_type_descriptor->name("MyBitMask");
    bitmask_type_descriptor->element_type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(
                TK_BOOLEAN));
    bitmask_type_descriptor->bound().push_back(8);
    DynamicTypeBuilder::_ref_type bitmask_builder {DynamicTypeBuilderFactory::get_instance()->create_type(
                                                    bitmask_type_descriptor)};
 */

// Add bitfield members to the bitmask type
MemberDescriptor::_ref_type bitfield_member_descriptor {traits<MemberDescriptor>::make_shared()};
bitfield_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_BOOLEAN));
bitfield_member_descriptor->name("flag0");
bitfield_member_descriptor->id(0);
bitmask_builder->add_member(bitfield_member_descriptor);
bitfield_member_descriptor = traits<MemberDescriptor>::make_shared();
bitfield_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_BOOLEAN));
bitfield_member_descriptor->name("flag1");
bitmask_builder->add_member(bitfield_member_descriptor);
bitfield_member_descriptor = traits<MemberDescriptor>::make_shared();
bitfield_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_BOOLEAN));
bitfield_member_descriptor->name("flag2");
bitmask_builder->add_member(bitfield_member_descriptor);
bitfield_member_descriptor = traits<MemberDescriptor>::make_shared();
bitfield_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_BOOLEAN));
bitfield_member_descriptor->name("flag5");
bitfield_member_descriptor->id(5);
bitmask_builder->add_member(bitfield_member_descriptor);
// Build the bitmask type
DynamicType::_ref_type bitmask_type =  bitmask_builder->build();

// Add a bitmask member to the struct
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
member_descriptor->name("my_bitmask");
member_descriptor->type(bitmask_type);
struct_builder->add_member(member_descriptor);
// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};

// Set and retrieve values for bitmask member.
uint8_t in_value {3}; // Setting both "flag0" and "flag1" simultaneously.
uint8_t out_value {0};
data->set_uint8_value(data->get_member_id_by_name("my_bitmask"), in_value);
data->get_uint8_value(out_value, data->get_member_id_by_name("my_bitmask"));

// Set and retrieve specific bitflag
bool in_bitflag_value = true;
bool out_bitflag_value = false;
DynamicData::_ref_type bitmask_data = data->loan_value(data->get_member_id_by_name("my_bitmask"));
bitmask_data->set_boolean_value(bitmask_data->get_member_id_by_name("flag5"), in_bitflag_value);
bitmask_data->get_boolean_value(out_bitflag_value, bitmask_data->get_member_id_by_name("flag5"));

For a detailed explanation about the XML definition of this type, please refer to XML Bitmask Types.

14.2.2.5. Alias Types

Alias types provide an alternative name to an already existing type. The TypeKind used to identify aliases is TK_ALIAS. Besides defining the alias name, the underlying type must be set using TypeDescriptor base_type property. Alias recursion is supported by defining another alias type as the base type.

Once the DynamicData is created, information can be accessed as if working with the base type.

typedef MyEnum MyAliasedEnum;
typedef string<100> MyAliasedBoundedString;
typedef MyAliasedEnum MyRecursiveAlias;

struct AliasStruct
{
    MyAliasedEnum my_aliased_enum;
    MyAliasedBoundedString my_aliased_bounded_string;
    MyRecursiveAlias my_recursive_alias;
};
<typedef name="MyAliasedEnum" type="nonBasic" nonBasicTypeName="MyEnum"/>
<!-- XSD does not allow to set bounds to aliased strings -->
<typedef name="MyAliasedBoundedString" type="string"/>
<typedef name="MyRecursiveAlias" type="nonBasic" nonBasicTypeName="MyAliasedEnum"/>

<struct name="AliasStruct">
    <member name="my_aliased_enum" type="nonBasic" nonBasicTypeName="MyAliasedEnum"/>
    <member name="my_aliased_bounded_string" type="nonBasic" nonBasicTypeName="MyAliasedBoundedString"/>
    <member name="my_recursive_alias" type="nonBasic" nonBasicTypeName="MyRecursiveAlias"/>
</struct>
// Define a struct type to contain the alias
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("AliasStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(type_descriptor)};

// Define an alias type for the enum
TypeDescriptor::_ref_type aliasenum_type_descriptor {traits<TypeDescriptor>::make_shared()};
aliasenum_type_descriptor->kind(TK_ALIAS);
aliasenum_type_descriptor->name("MyAliasedEnum");
aliasenum_type_descriptor->base_type(enum_type);
DynamicTypeBuilder::_ref_type aliasenum_builder {DynamicTypeBuilderFactory::get_instance()->
                                                         create_type(aliasenum_type_descriptor)};
// Build the alias type
DynamicType::_ref_type aliasenum_type = aliasenum_builder->build();

// Define an alias type for a bounded string
TypeDescriptor::_ref_type alias_bounded_string_type_descriptor {traits<TypeDescriptor>::make_shared()};
alias_bounded_string_type_descriptor->kind(TK_ALIAS);
alias_bounded_string_type_descriptor->name("MyAliasedBoundedString");
alias_bounded_string_type_descriptor->base_type(DynamicTypeBuilderFactory::get_instance()->
                create_string_type(100)->build());
DynamicTypeBuilder::_ref_type alias_bounded_string_builder {DynamicTypeBuilderFactory::get_instance()->
                                                                    create_type(
                                                                alias_bounded_string_type_descriptor)};
// Build the alias type for the bounded string
DynamicType::_ref_type alias_bounded_string_type = alias_bounded_string_builder->build();

// Define a recursive alias
TypeDescriptor::_ref_type recursive_alias_type_descriptor {traits<TypeDescriptor>::make_shared()};
recursive_alias_type_descriptor->kind(TK_ALIAS);
recursive_alias_type_descriptor->name("MyRecursiveAlias");
recursive_alias_type_descriptor->base_type(aliasenum_type);
DynamicTypeBuilder::_ref_type recursive_alias_builder {DynamicTypeBuilderFactory::get_instance()->
                                                               create_type(recursive_alias_type_descriptor)};
// Build the recursive alias type
DynamicType::_ref_type recursive_alias_type = recursive_alias_builder->build();

// Add alias enum member to the structure
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
member_descriptor->name("my_aliased_enum");
member_descriptor->type(aliasenum_type);
struct_builder->add_member(member_descriptor);
// Add alias bounded string member to the structure
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_aliased_bounded_string");
member_descriptor->type(alias_bounded_string_type);
struct_builder->add_member(member_descriptor);
// Add recursive alias member to the structure
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->name("my_recursive_alias");
member_descriptor->type(recursive_alias_type);
struct_builder->add_member(member_descriptor);

// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};

// Set and retrieve values for the alias enum member
MyEnum in_value {MyEnum::C};
int32_t out_value {0};
data->set_int32_value(data->get_member_id_by_name("my_alias_enum"), in_value);
data->get_int32_value(out_value, data->get_member_id_by_name("my_alias_enum"));

For a detailed explanation about the XML definition of this type, please refer to XML Alias Types.

14.2.2.6. Sequence types

Sequence types are one-dimensional collections of any type. The TypeKind used to identify sequences is TK_SEQUENCE. TypeDescriptor element_type property must be set with the collection’s type. Additionally, bound property must also be configured with the sequence’s maximum length, or LENGTH_UNLIMITED in case of unbounded sequences.

DynamicTypeBuilderFactory exposes the function DynamicTypeBuilderFactory::create_sequence_type to facilitate the creation of this type. This API requires the type stored in the collection and the collection’s bound, using LENGTH_UNLIMITED in case of unbounded sequences.

DynamicData class provides specific get_values() and set_values() functions for each primitive type, allowing users to easily work with sequences of primitive types. Primitive type promotion is also applicable for these methods. For sequences of more complex types, please refer to Managing Complex Types Data.

If a specific range of values within the sequence are to be modified, passing the starting index to get_values() / set_values() would only manage data from that element forward until the length of the given input. Specific collection’s element can be also be modified using the get_value() / set_value() passing the index of the element to be modified.

struct SequenceStruct
{
    sequence<MyBitMask> bitmask_sequence;
    sequence<short, 5> short_sequence;
};
<struct name="SequenceStruct">
    <member name="bitmask_sequence" type="nonBasic" nonBasicTypeName="MyBitMask" sequenceMaxLength="-1"/>
    <member name="short_sequence" sequenceMaxLength="5" type="int16"/>
</struct>
// Define a struct type to contain the sequence
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("SequenceStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(type_descriptor)};

// Define a member for the sequence
MemberDescriptor::_ref_type sequence_member_descriptor {traits<MemberDescriptor>::make_shared()};
sequence_member_descriptor->name("bitmask_sequence");
sequence_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_sequence_type(bitmask_type,
        static_cast<uint32_t>(LENGTH_UNLIMITED))->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_SEQUENCE);
    type_descriptor->element_type(bitmask_type);
    type_descriptor->bound().push_back(static_cast<uint32_t>(LENGTH_UNLIMITED));
    sequence_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(
            type_descriptor)->build());
 */

// Add the sequence member to the struct
struct_builder->add_member(sequence_member_descriptor);

sequence_member_descriptor = traits<MemberDescriptor>::make_shared();
sequence_member_descriptor->name("short_sequence");
sequence_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_sequence_type(
            DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT16), 5)->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_SEQUENCE);
    type_descriptor->element_type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT16));
    type_descriptor->bound().push_back(5);
    sequence_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(
            type_descriptor)->build());
 */

// Add the sequence member to the struct
struct_builder->add_member(sequence_member_descriptor);
// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};

// Set and retrieve values for the sequence member
Int16Seq in_value = {1, 2};
Int16Seq out_value;
data->set_int16_values(data->get_member_id_by_name("short_sequence"), in_value);
data->get_int16_values(out_value, data->get_member_id_by_name("short_sequence"));

DynamicData::_ref_type sequence_data {data->loan_value(data->get_member_id_by_name("short_sequence"))};
// Set the two latest possible values on the sequence
sequence_data->set_int16_values(3, in_value);
// Read every sequence value from index 1 to the end
sequence_data->get_int16_values(out_value, 1);

int16_t in_simple_value = 8;
int16_t out_simple_value;
sequence_data->set_int16_value(2, in_simple_value);
sequence_data->get_int16_value(out_simple_value, 2);

data->return_loaned_value(sequence_data);

For a detailed explanation about the XML definition of this type, please refer to XML Sequence Types.

14.2.2.7. Array types

Array types are multi-dimensional collections of any type. The TypeKind used to identify arrays is TK_ARRAY. TypeDescriptor element_type property must be set with the collection’s type. Additionally, bound property must be configured with the sequence containing the size of each dimension. Bound sequence must have at least one dimension and it is not allowed for any dimension to have size 0.

DynamicTypeBuilderFactory exposes the function DynamicTypeBuilderFactory::create_array_type to facilitate the creation of this type. This API requires the type stored in the collection and the sequence with the collection’s dimensions.

DynamicData class provides specific get_values() and set_values() functions for each primitive type, allowing users to easily work with arrays of primitives types. For arrays of more complex types, please refer to Managing Complex Types Data.

Note

Multi-dimensional arrays flatten every dimension into a single-dimension array.

Primitive type promotion is also applicable for these methods.

If a specific range of values within the array are to be modified, passing the starting index to get_values() / set_values() would only manage data from that element forward until the length of the given input. Specific collection’s element can be also be modified using the get_value() / set_value() passing the index of the element to be modified.

struct ArrayStruct
{
    long long_array[2][3][4];
};
<struct name="ArrayStruct">
    <member name="long_array" type="int32" arrayDimensions="2,3,4"/>
</struct>
// Define a struct type to contain the array
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("ArrayStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(type_descriptor)};
// Define a member for the array
MemberDescriptor::_ref_type array_member_descriptor {traits<MemberDescriptor>::make_shared()};
array_member_descriptor->name("long_array");
array_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_array_type(
            DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT32), { 2, 3, 4 })->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_ARRAY);
    type_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT32));
    type_descriptor->bound().push_back(2);
    type_descriptor->bound().push_back(3);
    type_descriptor->bound().push_back(4);
    array_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(
            type_descriptor)->build());
 */

// Add the array member to the struct
struct_builder->add_member(array_member_descriptor);
// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};

// Set and retrieve values for the array member
Int32Seq in_value = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 23, 24};
Int32Seq out_value;
data->set_int32_values(data->get_member_id_by_name("long_array"), in_value);
data->get_int32_values(out_value, data->get_member_id_by_name("long_array"));

DynamicData::_ref_type array_data {data->loan_value(data->get_member_id_by_name("long_array"))};
// Set the two latest possible values on the array
Int32Seq small_in_value = {0, 1};
array_data->set_int32_values(22, small_in_value);
// Read every array value from index 1 to the end
array_data->get_int32_values(out_value, 1);

int32_t in_simple_value = 8;
int32_t out_simple_value;
array_data->set_int32_value(2, in_simple_value);
array_data->get_int32_value(out_simple_value, 2);

data->return_loaned_value(array_data);

For a detailed explanation about the XML definition of this type, please refer to XML Array Types.

14.2.2.8. Map Types

Map types are a collection of key/value pair types. Access to the value element is done through the key which is unique within the map type. The TypeKind used to identify maps is TK_MAP. TypeDescriptor element_type property must be set with the map value type. TypeDescriptor key_type property must be set with the map key type. Allowed key types are signed and unsigned integer types and string types.

Note

Currently, wide string keys are not supported as map keys.

Additionally, bound property must also be configured with the map’s maximum length, or LENGTH_UNLIMITED in case of unbounded maps.

DynamicTypeBuilderFactory exposes the DynamicTypeBuilderFactory::create_map_type function to facilitate the creation of this type. This API requires the type of both the key and the value stored in the collection, and the collection’s bound, using LENGTH_UNLIMITED in case of unbounded maps.

Manipulating map types data is more complex. First the MemberId corresponding to a specific key must be retrieved using DynamicData::get_member_id_by_name API. This API either returns the MemberId corresponding to the existing key or, if the key does not exist yet, it creates the key and returns the memberId associated to the just created key. In order to call this method, the correct string representation of the key value must be passed. The map value can now be set using the API corresponding to the map value type. For complex map values, please refer to Managing Complex Types Data.

struct MapStruct
{
    map<string, MyAliasedBoundedString> string_alias_unbounded_map;
    map<short, long, 2> short_long_map;
};
<struct name="MapStruct">
    <member name="string_alias_unbounded_map" type="nonBasic" nonBasicTypeName="MyAliasedBoundedString" key_type="string" mapMaxLength="-1"/>
    <member name="short_long_map" type="int32" key_type="int16" mapMaxLength="2"/>
</struct>
// Define a struct type to contain the map
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("MapStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                      create_type(type_descriptor)};
// Define a member for the map
MemberDescriptor::_ref_type map_member_descriptor {traits<MemberDescriptor>::make_shared()};
map_member_descriptor->name("string_long_array_unbounded_map");
map_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_map_type(
            DynamicTypeBuilderFactory::get_instance()->create_string_type(static_cast<uint32_t>(
                LENGTH_UNLIMITED))->build(), alias_bounded_string_type, static_cast<uint32_t>(
                LENGTH_UNLIMITED))->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_MAP);
    type_descriptor->key_element_type(DynamicTypeBuilderFactory::get_instance()->create_string_type(
            static_cast<uint32_t>(LENGTH_UNLIMITED)->build());
    type_descriptor->element_type(alias_bounded_string_type);
    type_descriptor->bound().push_back(static_cast<uint32_t>(LENGTH_UNLIMITED));
    map_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(
            type_descriptor)->build());
 */

// Add the map member to the struct
struct_builder->add_member(map_member_descriptor);

map_member_descriptor = traits<MemberDescriptor>::make_shared();
map_member_descriptor->name("short_long_map");
map_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_map_type(
            DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT16),
            DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT32), 2)->build());

/* Alternative
    type_descriptor = traits<TypeDescriptor>::make_shared();
    type_descriptor->kind(TK_MAP);
    type_descriptor->key_element_type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT16));
    type_descriptor->element_type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT32));
    type_descriptor->bound().push_back(2);
    map_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_type(
            type_descriptor)->build());
 */

struct_builder->add_member(map_member_descriptor);
// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};

// Get the data loan of the map member
DynamicData::_ref_type map_data = data->loan_value(data->get_member_id_by_name("short_long_map"));

// Set and retrieve values for the map member
int32_t key {1};
int32_t in_value {2};
int32_t out_value;
map_data->set_int32_value(map_data->get_member_id_by_name(std::to_string(key)), in_value);
map_data->get_int32_value(out_value, map_data->get_member_id_by_name(std::to_string(key)));

// Return de data loan of the map member
data->return_loaned_value(map_data);

For a detailed explanation about the XML definition of this type, please refer to XML Map Types.

14.2.2.9. Structure Types

Structure types are an aggregation of members of different types. The TypeKind used to identify structures is TK_STRUCTURE. Structure types have single inheritance support, so a structure type might extend one other already defined structure. The structure type which is extended should be configured in the TypeDescriptor base_type property. Structure extensibility might be configured using TypeDescriptor extensibility_kind property.

Note

Currently, @nested builtin annotation is not supported.

Structure members must be configured using the DynamicTypeBuilder by calling the DynamicTypeBuilder::add_member function with the corresponding MemberDescriptor.

Note

Empty structures, with no members, are allowed.

Member name is configured using MemberDescriptor name property and the member type is set using type property. Structure members might be keyed to create topic instances by setting the MemberDescriptor is_key property. The behavior is the same as setting the @key builtin annotation. Additionally, MemberDescriptor default_value property might be set to configure the member default value, and MemberDescriptor id property sets explicitly the member ID. This behavior is the same as setting the @default and @id builtin annotations.

Note

Currently, Fast DDS-Gen does not support @default builtin annotation.

Note

Currently, Dynamic Language Binding API implementation does not support the following builtin annotations:

  • @optional

  • @must_understand

  • @external

  • @try_construct

Member data can be managed using the corresponding accessors for the underlying member type. Member ID might be retrieved using DynamicData::get_member_id_by_name API. For managing complex type members, please refer to Managing Complex Types Data.

struct InnerStruct
{
    @id(0x10) long first;
};

struct ParentStruct
{
    float first;
    long long second;
};

struct ComplexStruct : ParentStruct
{
    InnerStruct complex_member;
};
<struct name="InnerStruct">
    <!-- XML does not support setting Member ID -->
    <member name="first" type="int32"/>
</struct>

<!-- TODO(XTypes: Fix inheritance loading from XML profile) Fast DDS#4626 -->
<!-- <struct name="ParentStruct">
    <member name="first" type="float32"/>
    <member name="second" type="int64"/>
</struct>

<struct name="ComplexStruct" baseType="ParentStruct">
    <member name="complex_member" type="nonBasic" nonBasicTypeName="InnerStruct"/>
</struct> -->
// Create inner struct type
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(eprosima::fastdds::dds::TK_STRUCTURE);
type_descriptor->name("InnerStruct");
DynamicTypeBuilder::_ref_type builder {DynamicTypeBuilderFactory::get_instance()->create_type(type_descriptor)};
// Add members to the inner struct type
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                get_primitive_type(eprosima::fastdds::dds::TK_INT32));
member_descriptor->name("first");
member_descriptor->id(16);
builder->add_member(member_descriptor);
// Build the inner struct type
DynamicType::_ref_type inner_struct_type {builder->build()};

// Create parent struct type
TypeDescriptor::_ref_type parentstruct_type_descriptor {traits<TypeDescriptor>::make_shared()};
parentstruct_type_descriptor->kind(TK_STRUCTURE);
parentstruct_type_descriptor->name("ParentStruct");
DynamicTypeBuilder::_ref_type parentstruct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                            create_type(parentstruct_type_descriptor)};
// Add members to the parent struct type
MemberDescriptor::_ref_type parentstruct_member {traits<MemberDescriptor>::make_shared()};
parentstruct_member->name("first");
parentstruct_member->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_FLOAT32));
parentstruct_builder->add_member(parentstruct_member);
parentstruct_member = traits<MemberDescriptor>::make_shared();
parentstruct_member->name("second");
parentstruct_member->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT64));
parentstruct_builder->add_member(parentstruct_member);
// Build the parent struct type
DynamicType::_ref_type parentstruct_type = parentstruct_builder->build();

// Create complex struct type
TypeDescriptor::_ref_type complexstruct_type_descriptor {traits<TypeDescriptor>::make_shared()};
complexstruct_type_descriptor->kind(TK_STRUCTURE);
complexstruct_type_descriptor->name("ComplexStruct");
complexstruct_type_descriptor->base_type(parentstruct_type);
DynamicTypeBuilder::_ref_type complexstruct_builder {DynamicTypeBuilderFactory::get_instance()->
                                                             create_type(complexstruct_type_descriptor)};
// Add members to the complex struct type
MemberDescriptor::_ref_type complexstruct_member {traits<MemberDescriptor>::make_shared()};
complexstruct_member->name("complex_member");
complexstruct_member->type(inner_struct_type);
complexstruct_builder->add_member(complexstruct_member);

// Build the complex struct type
DynamicType::_ref_type complexstruct_type = complexstruct_builder->build();
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(complexstruct_type)};

// Set and retrieve values for member of type float
float in_value {3.14};
float out_value {0.0};
data->set_float32_value(data->get_member_id_by_name("first"), in_value);
data->get_float32_value(out_value, data->get_member_id_by_name("first"));

For a detailed explanation about the XML definition of this type, please refer to XML Structure Types.

14.2.2.10. Union Types

Union types are a special type of structure type where only one member exists. The TypeKind used to identify unions is TK_UNION. Member selection is performed by setting another special member called discriminator. The discriminator type must be defined using TypeDescriptor discriminator_type property. Supported discriminator TypeKind are the following:

  • TK_BOOLEAN

  • TK_BYTE

  • TK_CHAR8

  • TK_CHAR16

  • TK_INT8

  • TK_UINT8

  • TK_INT16

  • TK_UINT16

  • TK_INT32

  • TK_UINT32

  • TK_INT64

  • TK_UINT64

  • TK_ENUM

  • TK_ALIAS that resolves, directly or indirectly to one of the aforementioned types.

Union extensibility might be configured using TypeDescriptor extensibility_kind property.

Note

Currently, @nested builtin annotation is not supported.

Union members must be configured using the DynamicTypeBuilder by calling the DynamicTypeBuilder::add_member function with the corresponding MemberDescriptor. At least one union member must be added to the union type. Union member name is configured using MemberDescriptor name property and the member type is set using type property. It is also mandatory to either set MemberDescriptor is_default_label property or configure the label property. This latest property indicates the discriminator values that select this specific member. If no labels are configured, then the flag indicating the member to be the default one, must be set. Only one union member must be configured as default.

Additionally, MemberDescriptor default_value property might be set to configure the member default value, and MemberDescriptor id property sets explicitly the member ID. This behavior is the same as setting the @default and @id builtin annotations.

Note

Currently, Fast DDS-Gen does not support @default builtin annotation.

Note

Currently, Dynamic Language Binding API implementation does not support the following builtin annotations:

  • @optional

  • @must_understand

  • @external

  • @try_construct

Member data can be managed using the corresponding accessors for the underlying member type. Setting a member automatically changes the discriminator value selecting the set member. When reading a member, the discriminator must be selecting the member being read. Member ID might be retrieved using DynamicData::get_member_id_by_name API. For managing complex type members, please refer to Managing Complex Types Data.

union InnerUnion switch (short)
{
    case 0:
        @id(0x10) PrimitivesStruct first;
    case 1:
    default:
        long long second;
};

union ComplexUnion switch (long)
{
    case 0:
    case 1:
        long third;
    default:
        InnerUnion fourth;
};
<union name="InnerUnion">
    <discriminator type="int16"/>
    <case>
        <caseDiscriminator value="0"/>
        <member name="first" type="nonBasic" nonBasicTypeName="PrimitivesStruct"/>
    </case>
    <case>
        <caseDiscriminator value="1"/>
        <caseDiscriminator value="default"/>
        <member name="second" type="int64"/>
    </case>
</union>
<union name="ComplexUnion">
    <discriminator type="int32"/>
    <case>
        <caseDiscriminator value="0"/>
        <caseDiscriminator value="1"/>
        <member name="third" type="int32"/>
    </case>
    <case>
        <caseDiscriminator value="default"/>
        <member name="fourth" type="nonBasic" nonBasicTypeName="InnerUnion"/>
    </case>
</union>
// Define a struct type to contain the union
// Create the inner union
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_UNION);
type_descriptor->name("InnerUnion");
type_descriptor->discriminator_type(DynamicTypeBuilderFactory::get_instance()->
                get_primitive_type(TK_INT16));
DynamicTypeBuilder::_ref_type builder {DynamicTypeBuilderFactory::get_instance()->
                                               create_type(type_descriptor)};
// Add members to the inner union type
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
member_descriptor->type(struct_type);
member_descriptor->name("first");
member_descriptor->id(16);
member_descriptor->label({0});
builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                get_primitive_type(TK_INT64));
member_descriptor->name("second");
member_descriptor->label({1});
member_descriptor->is_default_label(true);
builder->add_member(member_descriptor);
// Build the inner union type
DynamicType::_ref_type inner_union_type {builder->build()};

// Create a complex union type
type_descriptor = traits<TypeDescriptor>::make_shared();
type_descriptor->kind(TK_UNION);
type_descriptor->name("ComplexUnion");
type_descriptor->discriminator_type(DynamicTypeBuilderFactory::get_instance()->
                get_primitive_type(TK_INT32));
builder = DynamicTypeBuilderFactory::get_instance()->create_type(type_descriptor);
// Add members to the complex union type
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->
                get_primitive_type(TK_INT32));
member_descriptor->name("third");
member_descriptor->label({0, 1});
builder->add_member(member_descriptor);
member_descriptor = traits<MemberDescriptor>::make_shared();
member_descriptor->type(inner_union_type);
member_descriptor->name("fourth");
member_descriptor->is_default_label(true);
builder->add_member(member_descriptor);
// Build the complex union type
DynamicType::_ref_type union_type {builder->build()};

// Create dynamic data based on the union type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(union_type)};
// Get the loan for the InnerUnion member
DynamicData::_ref_type union_data = data->loan_value(data->get_member_id_by_name("InnerUnion"));

// Set and retrieve values for the long long member within InnerUnion member
int64_t in_value {2};
int64_t out_value;
union_data->set_int64_value(union_data->get_member_id_by_name("second"), in_value);
union_data->get_int64_value(out_value, union_data->get_member_id_by_name("second"));
// Return de data loan of the member
data->return_loaned_value(union_data);

For a detailed explanation about the XML definition of this type, please refer to XML Union Types.

14.2.2.11. Bitset Types

Bitset types are an aggregation of bitfields. The TypeKind used to identify bitsets is TK_BITSET. bound property contains the sequence with the bitfield’s bitcount (number of bits). In order to be consistent, the length of the bound sequence must agree with the number of bitfields. Bitset types have single inheritance support, so a bitset type might extend one other already defined bitset. The bitset type which is extended should be configured in the TypeDescriptor base_type property.

Bitfields must be configured using the DynamicTypeBuilder by calling the DynamicTypeBuilder::add_member function with the corresponding MemberDescriptor. At least one bitfield is required for the bitset to be consistent. Bitfield name is configured using MemberDescriptor name property, and the bitfield initial bit position is set using MemberDescriptor id property.

Note

For derived bitsets, the first bitfield initial position must be after the bits defined by the parent bitset type.

A bitfield manages exclusively a set of bits, so no bitfield superposition is allowed. Additionally, MemberDescriptor type property might be set to configure an integer type to access bitfield data. If not set, the minimum unsigned integer type is used instead:

Number of bits

C++ holder type

1

bool

2-8

uint8_t

9-16

uint16_t

17-32

uint32_t

33-64

uint64_t

Each bitfield (or member) works like its primitive type with the only difference that the internal storage only modifies the involved bits instead of the full primitive value.

bitset ParentBitSet
{
    bitfield<3> a;
    bitfield<1> b;
    bitfield<4>;
    bitfield<10> c;
    bitfield<12, short> d;
};

bitset ChildBitSet : ParentBitSet
{
    bitfield<1> e;
    bitfield<20, unsigned long> f;
};

struct BitsetStruct
{
   ChildBitSet my_bitset;
};
<bitset name="ParentBitset">
    <bitfield name="a" bit_bound="3"/>
    <bitfield name="b" bit_bound="1"/>
    <bitfield bit_bound="4"/>
    <bitfield name="c" bit_bound="10"/>
    <bitfield name="d" bit_bound="12" type="int16"/>
</bitset>

<!-- TODO(XTypes: Fix inheritance loading from XML profile) Fast DDS#4626 -->
<!--<bitset name="ChildBitSet" baseType="ParentBitSet">
    <bitfield name="e" bit_bound="1"/>
    <bitfield name="f" bit_bound="20" type="uint32"/>
</bitset>

<struct name="BitsetStruct">
    <member name="my_bitset" type="nonBasic" nonBasicTypeName="ChildBitSet"/>
</struct>-->
// Define a struct type to contain the bitset
TypeDescriptor::_ref_type struct_type_descriptor {traits<TypeDescriptor>::make_shared()};
struct_type_descriptor->kind(TK_STRUCTURE);
struct_type_descriptor->name("BitsetStruct");
DynamicTypeBuilder::_ref_type struct_builder {DynamicTypeBuilderFactory::get_instance()->create_type(
                                                  struct_type_descriptor)};

// Define type for parent bitset
TypeDescriptor::_ref_type bitset_type_descriptor {traits<TypeDescriptor>::make_shared()};
bitset_type_descriptor->kind(TK_BITSET);
bitset_type_descriptor->name("ParentBitSet");
bitset_type_descriptor->bound({3, 1, 10, 12});
DynamicTypeBuilder::_ref_type bitset_builder {DynamicTypeBuilderFactory::get_instance()->create_type(
                                                  bitset_type_descriptor)};
// Add members to the bitset type
MemberDescriptor::_ref_type bitset_member_descriptor {traits<MemberDescriptor>::make_shared()};
bitset_member_descriptor->name("a");
bitset_member_descriptor->id(0);
bitset_builder->add_member(bitset_member_descriptor);
bitset_member_descriptor = traits<MemberDescriptor>::make_shared();
bitset_member_descriptor->name("b");
bitset_member_descriptor->id(3);
bitset_builder->add_member(bitset_member_descriptor);
bitset_member_descriptor = traits<MemberDescriptor>::make_shared();
bitset_member_descriptor->name("c");
bitset_member_descriptor->id(8);
bitset_builder->add_member(bitset_member_descriptor);
bitset_member_descriptor = traits<MemberDescriptor>::make_shared();
bitset_member_descriptor->name("d");
bitset_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT16));
bitset_member_descriptor->id(18);
bitset_builder->add_member(bitset_member_descriptor);
// Build the bitset type
DynamicType::_ref_type parentbitset_type = bitset_builder->build();

// Create child bitset type
TypeDescriptor::_ref_type childbitset_type_descriptor {traits<TypeDescriptor>::make_shared()};
childbitset_type_descriptor->kind(TK_BITSET);
childbitset_type_descriptor->name("ChildBitSet");
childbitset_type_descriptor->base_type(parentbitset_type);
childbitset_type_descriptor->bound({1, 20});
DynamicTypeBuilder::_ref_type childbitset_builder {DynamicTypeBuilderFactory::get_instance()->create_type(
                                                       childbitset_type_descriptor)};
// Add members to the child bitset type
MemberDescriptor::_ref_type childbitset_member_descriptor {traits<MemberDescriptor>::make_shared()};
childbitset_member_descriptor->name("e");
childbitset_member_descriptor->id(30);
childbitset_builder->add_member(childbitset_member_descriptor);
childbitset_member_descriptor = traits<MemberDescriptor>::make_shared();
childbitset_member_descriptor->name("d");
childbitset_member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_UINT32));
childbitset_member_descriptor->id(31);
childbitset_builder->add_member(childbitset_member_descriptor);
// Build the child bitset type
DynamicType::_ref_type bitset_type = childbitset_builder->build();

// Add the bitset member to the struct
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
member_descriptor->name("my_bitset");
member_descriptor->type(bitset_type);
struct_builder->add_member(member_descriptor);
// Build the struct type
DynamicType::_ref_type struct_type {struct_builder->build()};
// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(struct_type)};
// Get the loan for the bitset member
DynamicData::_ref_type bitset_data = data->loan_value(data->get_member_id_by_name("my_bitset"));

// Set and retrieve bitfield values
int16_t in_value {2};
int16_t out_value;
bitset_data->set_int16_value(bitset_data->get_member_id_by_name("d"), in_value);
bitset_data->get_int16_value(out_value, bitset_data->get_member_id_by_name("d"));
// Return de data loan of the member
data->return_loaned_value(bitset_data);

For a detailed explanation about the XML definition of this type, please refer to XML Bitset Types.

14.2.2.12. Annotations
14.2.2.12.1. Custom annotations

Both types and type members might be annotated using DynamicTypeBuilder::apply_annotation and DynamicTypeBuilder::apply_annotation_to_member API respectively.

Annotations are defined using an AnnotationDescriptor which provides two properties: type and value. The annotation type must be the DynamicType representing the annotation being applied. The TypeKind used to identify annotations is TK_ANNOTATION. The annotation name is set in TypeDescriptor name property.

The annotation type might have any number of parameters. Annotation parameters must be configured using the DynamicTypeBuilder by calling the DynamicTypeBuilder::add_member function with the corresponding MemberDescriptor. Annotation parameters must define the annotation parameter name in MemberDescriptor name property, and the parameter type using type property. Only the following types can be used to define an annotation parameter:

Note

Currently, wide string types are not supported as annotation parameters.

Annotation parameter values are defined with AnnotationDescriptor value property using AnnotationDescriptor::set_value(). The annotation parameter name provided to the API must coincide with the one defined with the annotation type. The annotation parameter value must be converted to its string representation.

Note

Currently, custom annotations are not supported with XML DynamicTypes.

@annotation MyAnnotation
{
    short length;
};

@MyAnnotation(length = 5)
struct AnnotatedStruct
{
    @MyAnnotation(length = 10) string string_var;
};
<!-- XML Types Profiles does not support defining/setting custom annotations -->
// Create the structure to annotate
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
type_descriptor->kind(TK_STRUCTURE);
type_descriptor->name("AnnotatedStruct");
DynamicTypeBuilder::_ref_type type_builder {DynamicTypeBuilderFactory::get_instance()->
                                                    create_type(type_descriptor)};
MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
member_descriptor->name("string_var");
member_descriptor->type(DynamicTypeBuilderFactory::get_instance()->create_string_type(static_cast<uint32_t>(
            LENGTH_UNLIMITED))->build());
type_builder->add_member(member_descriptor);

// Create the annotation type
AnnotationDescriptor::_ref_type annotation_descriptor {traits<AnnotationDescriptor>::make_shared()};
TypeDescriptor::_ref_type annotation_type {traits<TypeDescriptor>::make_shared()};
annotation_type->kind(TK_ANNOTATION);
annotation_type->name("MyAnnotation");
DynamicTypeBuilder::_ref_type annotation_builder {DynamicTypeBuilderFactory::get_instance()->
                                                          create_type(annotation_type)};

// Add members to the annotation type
MemberDescriptor::_ref_type annotation_parameter {traits<MemberDescriptor>::make_shared()};
annotation_parameter->name("length");
annotation_parameter->type(DynamicTypeBuilderFactory::get_instance()->get_primitive_type(TK_INT16));
annotation_builder->add_member(annotation_parameter);
// Set the annotation type using the annotation descriptor
annotation_descriptor->type(annotation_builder->build());
// Set the value of the annotation
annotation_descriptor->set_value("length", std::to_string(5));
// Apply the annotation to the structure
type_builder->apply_annotation(annotation_descriptor);

// Reuse annotation descriptor to annotate struct member
annotation_descriptor = traits<AnnotationDescriptor>::make_shared();
annotation_descriptor->type(annotation_builder->build());
annotation_descriptor->set_value("length", std::to_string(10));

DynamicTypeMember::_ref_type member;
type_builder->get_member_by_name(member, "string_var");
type_builder->apply_annotation_to_member(member->get_id(), annotation_descriptor);
14.2.2.12.2. Builtin annotations

Beside the user-defined custom annotations, there are a number of builtin annotations that have already mentioned throughout this section.

The table below summarizes the builtin annotations that can be applied using the Dynamic Language Binding API. Please, refer to builtin annotations for the complete list and their behavior.

Builtin annotation

Dynamic Language Binding API

Dynamic Language Binding support

XML Dynamic Type profiles support

IDL Parsing Dynamic Type support

@appendable

TypeDescriptor extensibility_kind property.

@bit_bound

TypeDescriptor bound property for Bitset Types.
MemberDescriptor type property for Enumeration Types.

✅❌ (Enumeration types not configurable).

@default

MemberDescriptor default_value property.

default_literal

MemberDescriptor is_default_label property.

@extensibility

TypeDescriptor extensibility_kind property.

@external

MemberDescriptor is_shared property.

@final

TypeDescriptor extensibility_kind property.

@id

MemberDescriptor id property.

@key / @Key

MemberDescriptor is_key property.

@mutable

TypeDescriptor extensibility_kind property.

@nested

TypeDescriptor is_nested property.

@optional

MemberDescriptor is_optional property.

@position

MemberDescriptor id property.

@try_construct

MemberDescriptor try_construct_kind property.

@value

MemberDescriptor default_value property.

@verbatim

VerbatimTextDescriptor

14.2.2.13. Managing Complex Types Data

Some DynamicData instances manage complex types that cannot be directly modified with the primitive getters and setters. Dynamic Language Binding provides two possible approaches for managing complex data types:

  1. DynamicData::get_complex_value and DynamicData::set_complex_value: This API allows to get/set generic DynamicData. The main difference with the next approach is that this API performs always a copy.

  2. DynamicData::loan_value: this API allows to loan a reference to a DynamicData to work with preventing the data copy. DynamicData::return_loaned_value must be called to return the loan. Calling DynamicData::loan_value for an already loaned value will fail.

The following snippet includes an example of managing complex data using the same structure as the one defined in Structure types:

// Create dynamic data based on the struct type
DynamicData::_ref_type data {DynamicDataFactory::get_instance()->create_data(complexstruct_type)};

// Get/Set complex API (copy)
DynamicData::_ref_type complex_data;
data->get_complex_value(complex_data, data->get_member_id_by_name("complex_member"));
// Set data
int32_t in_value {10};
complex_data->set_int32_value(complex_data->get_member_id_by_name("first"), in_value);
data->set_complex_value(data->get_member_id_by_name("complex_member"), complex_data);

// Loan API
DynamicData::_ref_type loan_data = data->loan_value(data->get_member_id_by_name("complex_member"));
loan_data->set_int32_value(loan_data->get_member_id_by_name("first"), in_value);
int32_t out_value;
loan_data->get_int32_value(out_value, loan_data->get_member_id_by_name("first"));
data->return_loaned_value(loan_data);

14.3. Serialization Utilities

Fast DDS provides methods to serialize XTypes objects, enabling efficient data exchange and manipulation within distributed systems. Serialization is a crucial process in data distribution services, as it converts complex data structures into a format that can be easily transmitted and reconstructed across different platforms and programming environments.

14.3.1. Dynamic Type to IDL

The method idl_serialize serializes a DynamicType object to its IDL representation.

Note

The conversion to IDL only supports the following builtin annotations: @bit_bound, @extensibility, @key, and @position.

Warning

The conversion to IDL of a Bitset with inheritance merges derived Bitsets with their base Bitset.

Warning

The conversion to IDL dismisses values explicitly set to their default value. For example, the default @bit_bound value of a Bitmask is 32. If a user were to explicitly set the @bit_bound value of a Bitmask to 32 and then serialize the DynamicType to IDL, the @bit_bound would not be included in the IDL.

14.3.1.1. Example: Convert a discovered type to IDL format

The following example demonstrates how to use the idl_serialize method in Fast DDS to convert discovered types to IDL format. Each time the subscriber discovers a new DataReader or DataWriter, it uses the DynamicTypeBuilderFactory to build a DynamicType and serialize it to IDL format. Please refer to Remote type discovery and endpoint matching section for more details on how to implement remote type discovery.

/* Custom Callback on_data_reader_discovery */
void on_data_reader_discovery(
        DomainParticipant* /* participant */,
        eprosima::fastdds::rtps::ReaderDiscoveryStatus /* reason */,
        const eprosima::fastdds::dds::SubscriptionBuiltinTopicData& info,
        bool& /* should_be_ignored */) override
{
    // Get remote type information
    xtypes::TypeObject remote_type_object;
    if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
                info.type_information.type_information.complete().typeid_with_size().type_id(),
                remote_type_object))
    {
        // Error
        return;
    }

    // Build remotely discovered type
    DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
        remote_type_object)->build();

    // Serialize DynamicType into its IDL representation
    std::stringstream idl;
    idl_serialize(remote_type, idl);

    // Print IDL representation
    std::cout << "Type discovered:\n" << idl.str() << std::endl;
}

/* Custom Callback on_data_writer_discovery */
void on_data_writer_discovery(
        DomainParticipant* /* participant */,
        eprosima::fastdds::rtps::WriterDiscoveryStatus /*reason*/,
        const eprosima::fastdds::dds::PublicationBuiltinTopicData& info,
        bool& /* should_be_ignored */) override
{
    // Get remote type information
    xtypes::TypeObject remote_type_object;
    if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
                info.type_information.type_information.complete().typeid_with_size().type_id(),
                remote_type_object))
    {
        // Error
        return;
    }

    // Build remotely discovered type
    DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
        remote_type_object)->build();

    // Serialize DynamicType into its IDL representation
    std::stringstream idl;
    idl_serialize(remote_type, idl);

    // Print IDL representation
    std::cout << "Type discovered:\n" << idl.str() << std::endl;
}

14.3.2. DynamicData to JSON

In the context of DDS (Data Distribution Service), DynamicType represents the structure of the data being distributed across the system. Each DynamicData object corresponds to an object of the type represented by its DynamicType, providing functionalities to access and modify data values. To enhance interoperability and readability, it is often useful to serialize DynamicData into a more manageable format, to enable easier data processing and analysis across different systems and applications. The method json_serialize converts a DynamicData object into a JSON object, then dumped into a std::ostream.

14.3.2.1. Supported Types

This section provides the serialization of DynamicData to JSON ostream for all supported types.

14.3.2.1.1. Primitives

Primitive types are the basic building blocks for every DynamicType. Below is an example of the definition of primitive types in IDL:

struct PrimitivesStruct
{
    boolean my_bool;
    octet my_octet;
    char my_char;
    wchar my_wchar;
    long my_long;
    unsigned long my_ulong;
    int8 my_int8;
    uint8 my_uint8;
    short my_short;
    unsigned short my_ushort;
    long long my_longlong;
    unsigned long long my_ulonglong;
    float my_float;
    double my_double;
    long double my_longdouble;
};

A DynamicData object corresponding to the type represented above would be serialized as follows:

{
    "my_bool": false,
    "my_octet": 0,
    "my_char": "\u0000",
    "my_wchar": "\u0000",
    "my_long": 0,
    "my_ulong": 0,
    "my_int8": 0,
    "my_uint8": 0,
    "my_short": 0,
    "my_ushort": 0,
    "my_longlong": 0,
    "my_ulonglong": 0,
    "my_float": 0.0,
    "my_double": 0.0,
    "my_longdouble": 0.0
}
14.3.2.1.2. Strings

String types are used to represent sequences of characters, which are essential for handling textual data within the system. The following example shows the definition of string types in IDL:

struct StringsStruct
{
    string my_string;
    wstring my_wstring;
    string<41925> my_bounded_string;
    wstring<20925> my_bounded_wstring;
};

A DynamicData object corresponding to the type represented above would be serialized as follows:

{
    "my_string": "",
    "my_wstring": "",
    "my_bounded_string": "",
    "my_bounded_wstring": ""
}
14.3.2.1.3. Enumerations

Enumeration types represent a fixed set of named values, making it easier to work with a predefined list of options. Below is an example of the definition of enumeration types in IDL:

enum MyEnum
{
    A,
    B,
    C
};

struct EnumStruct
{
    MyEnum my_enum;
};

The previous DynamicData object can be serialized in two different formats, eProsima and OMG, providing flexibility depending on the required interoperability and compatibility with other systems. The previous DynamicData object would be serialized as follows in the different formats:

{
    "my_enum": {
        "name": "A",
        "value": 0
    }
}
{
    "my_enum": "A"
}
14.3.2.1.4. Bitmasks

Bitmask types allow the representation of a set of flags in a single value, which can be useful for storing multiple boolean options compactly. Here is an example of the definition of bitmask types in IDL:

@bit_bound(8)
bitmask MyBitMask
{
    @position(0) flag0,
    flag1,
    flag2,
    @position(5) flag5
};

struct BitmaskStruct
{
    MyBitMask my_bitmask;
};

Bitmask also present different serialized structures in the different formats eProsima and OMG. The previous DynamicData object would be serialized as follows in the different formats:

{
    "my_bitmask": {
        "active": [],
        "binary": "00000000",
        "value": 0
    }
}
{
    "my_bitmask": 0
}
14.3.2.1.5. Sequences

Sequence types are used to represent ordered collections of elements, similar to arrays but with dynamic length. Below is an example of the definition of sequence types in IDL:

struct SequenceStruct
{
    sequence<MyBitMask> bitmask_sequence;
    sequence<short, 5> short_sequence;
};

A DynamicData object corresponding to the type represented above would be serialized as follows:

{
    "bitmask_sequence": [],
    "short_sequence": []
}
14.3.2.1.6. Arrays

Array types are used to represent fixed-size collections of elements. The following example shows the definition of array types in IDL:

struct ArrayStruct
{
    long long_array[2][3];
};

A DynamicData object corresponding to the type represented above would be serialized as follows:

{
    "long_array": [
        [
            0,
            0,
            0
        ],
        [
            0,
            0,
            0
        ]
    ]
}
14.3.2.1.7. Maps

Map types represent collections of key-value pairs, allowing for the efficient lookup of values based on unique keys. Below is an example of the definition of map types in IDL:

struct MapStruct
{
    map<string, MyAliasedBoundedString> string_alias_unbounded_map;
    map<short, long, 2> short_long_map;
};

A DynamicData object corresponding to the type represented above would be serialized as follows:

{
    "short_long_map": null,
    "string_alias_unbounded_map": null
}
14.3.2.1.8. Structures

Structure types are used to group different types of data together. Here is an example of the definition of structure types in IDL:

struct InnerStruct
{
    @id(0x10) long first;
};

struct ParentStruct
{
    float first;
    long long second;
};

struct ComplexStruct : ParentStruct
{
    InnerStruct complex_member;
};

A DynamicData object corresponding to the type represented above would be serialized as follows:

{
    "complex_member": {
        "first": 0
    },
    "first": 0.0,
    "second": 0
}
14.3.2.1.9. Unions

Union types are a special type of structure type where only one member exists. Below is an example of the definition of union types in IDL:

union InnerUnion switch (short)
{
    case 0:
        @id(0x10) PrimitivesStruct first;
    case 1:
    default:
        long long second;
};

union ComplexUnion switch (long)
{
    case 0:
    case 1:
        long third;
    default:
        InnerUnion fourth;
};

A DynamicData object corresponding to the type represented above would be serialized as follows:

{
    "inner_union": {
        "second": 0
    },
    "complex_union": {
        "fourth": {
            "second": 0
        }
    }
}
14.3.2.1.10. Bitsets

Bitset types are a specialized type of structure where individual bits can be accessed and manipulated. Below is an example of the definition of bitset types in IDL:

bitset MyBitSet
{
    bitfield<3> a;
    bitfield<1> b;
    bitfield<4>;
    bitfield<10> c;
    bitfield<12, short> d;
};

struct BitsetStruct
{
   MyBitSet my_bitset;
};

A DynamicData object corresponding to the type represented above would be serialized as follows:

{
    "my_bitset": {
        "a": 0,
        "b": 0,
        "c": 0,
        "d": 0
    }
}
14.3.2.2. Example: Convert received data into JSON format

The following code demonstrates how to use the json_serialize function in Fast DDS to serialize received data into a more manageable and understandable JSON format. Each time the subscriber receives new data, the corresponding DynamicData can be obtained from the DynamicDataFactory and serialized into a JSON string format. Please refer to Remote type discovery and endpoint matching section for more details on how to implement remote type discovery.

void on_data_available(
        DataReader* reader)
{
    // Dynamic DataType
    DynamicData::_ref_type new_data =
            DynamicDataFactory::get_instance()->create_data(dyn_type_);

    SampleInfo info;

    while ((RETCODE_OK == reader->take_next_sample(&new_data, &info)))
    {
        std::stringstream output;
        output << std::setw(4);

        // Serialize DynamicData into JSON string format
        json_serialize(new_data, DynamicDataJsonFormat::EPROSIMA, output);
        std::cout << "Message received:\n" << output.str() << std::endl;
    }
}

// DynamicType created in discovery callback
DynamicType::_ref_type dyn_type_;

14.4. Dynamic Types IDL Parsing

Fast DDS supports the implementation of Dynamic Language Binding for parsing IDL files at runtime to generate dynamic data types. The DynamicTypeBuilderFactory::create_type_w_uri API allows users to provide a URI pointing to an IDL file. Fast DDS will process the file and return the corresponding DynamicTypeBuilder, which can then be used to create a DynamicType.

This feature enables applications to dynamically load type definitions from IDL files instead of relying solely on pre-generated types or XML profiles. This enhances flexibility, as new data types can be introduced without modifying and recompiling the application.

14.4.1. Type definition

Below, the types supported by eProsima Fast DDS IDL parsing are presented. For further information about the supported Dynamic Language Binding, please, refer to Supported Types.

The following types are currently not supported by the IDL parsing feature:

14.4.2. Example

Fast DDS application can use dynamic types generated in runtime just by loading the corresponding IDL files into the DynamicTypeBuilderFactory using DynamicTypeBuilderFactory::create_type_w_uri. After getting the DynamicType, objects of DynamicPubSubType class might be instantiated and used to write/read data.

Note

The preprocessor can be manually selected using DynamicTypeBuilderFactory::set_preprocessor

The following snippet shows the previously explained steps:

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Optional: Set the preprocessor to be executed before parsing the IDL
DynamicTypeBuilderFactory::get_instance()->set_preprocessor("<optional_path_to_your_preprocessor_executable>");

// Load the IDL file
std::string idl_file = "<path_to_idl>.idl";
std::string type_name = "YourType";
std::vector<std::string> include_paths;
include_paths.push_back("<path/to/folder/containing/included/idl/files>");

// Retrieve the instance of the desired type
DynamicTypeBuilder::_ref_type dyn_type_builder = 
        DynamicTypeBuilderFactory::get_instance()->create_type_w_uri(idl_file, type_name, include_paths);

// Register dynamic type
TypeSupport dyn_type_support(new DynamicPubSubType(dyn_type_builder->build()));
dyn_type_support.register_type(participant, nullptr);

// Create a Topic with the registered type.
Topic* topic =
        participant->create_topic("topic_name", dyn_type_support.get_type_name(), TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

Note

Type compatibility rules among evolved types are still unsupported in Fast DDS.

15. Typical Use-Cases

Fast DDS is highly configurable, which allows for its use in a large number of scenarios. This section provides configuration examples for the following typical use cases when dealing with distributed systems:

  • Large Data mode and Fast DDS over TCP. Describes how to configure Fast DDS to use the LARGE_DATA builtin transports mode. This mode enables efficient utilization of TCP transport without the need for constant reconfiguration during deployment changes. It optimizes communication performance for large data samples over lossy networks by employing a combination of UDP and TCP/SHM transports.

  • Fast DDS over WIFI. Presents a case where Discovery through multicast communication is a challenge. This example shows how to:

  • Well Known Network Deployments. Describes a situation where the entire entity network topology (Participants, Publishers, Subscribers, and their addresses and ports) are known beforehand. In these kind of environments, Fast DDS allows to completely avoid the discovery phase configuring a STATIC discovery mechanism.

  • Topics with many subscribers. In cases where there are many DataReaders subscribed to the same Topic, using multicast delivery can help reducing the overhead in the network and CPU.

  • Large Data Rates. Presents configuration options that can improve the performance in scenarios where the amount of data exchanged between a Publisher and a Subscriber is large, either because of the data size or because the message rate. The examples describe how to:

  • Real-time behavior. Describes the configuration options that allows using Fast DDS on a real-time scenario. The examples describe how to:

    • Configure memory management to avoid dynamic memory allocation (see Tuning allocations).

    • Limit the blocking time of API functions to have a predictable response time (see Non-blocking calls).

  • Reduce memory usage. For use cases with memory consumption constraints, Fast DDS can be configured to reduce memory footprint to a minimum by adjusting different QoS policies.

  • Zero-Copy communication. Under certain constraints, Fast DDS can provide application level communication between publishing and subscribing nodes avoiding any data copy during the process.

  • Unique network flows. This use case illustrates the APIs that allow for the request of unique network flows, and for the identification of those in use.

  • Dynamic network interfaces. If the network interfaces are expected to change while the application is running, Fast DDS provides an easy way of re-scanning the available interfaces and including them.

  • Statistics module. This use case explains how to enable the Statistics module within the monitored application, and how to create a statistics monitoring application.

  • ROS 2 using Fast DDS middleware. Since Fast DDS is the default middleware implementation in every OSRF Robot Operation System 2 (ROS 2) long term (LTS) releases and most of the non-LTS releases, this documentation includes a whole independent section to show the use of the library in ROS 2, and how to take full advantage of Fast DDS wide set of capabilities in a ROS 2 project.

  • How to use eProsima DDS Record and Replay. Instructions on how to tune your application to be able to record and replay your DDS messages using eProsima DDS Record and Replay.

  • Request-Reply communication. Although Fast DDS provides a Publisher-Subscriber communication protocol, it offers a mechanism to use Request-Reply communications. This use case explains how to use the APIs to communicate two application using Request-Reply.

  • Remote type discovery and endpoint matching. This use case leverages the Remote Data Types Discovery to create endpoints and start communicating with remote discovered endpoints with previously unknown data types.

15.1. Large Data mode and Fast DDS over TCP

As explained in TCP Transport, Fast DDS offers the possibility to communicate nodes within distributed applications with DDS over a TCP transport layer. This has the advantage of leveraging the builtin flow control and reliability of the TCP protocol, which in the context of DDS applications is best suited for the transmission of large payloads, i.e. large data samples, over lossy networks. Examples of such cases would be transmitting video or large point clouds resulting from laser scanning over WiFi links.

The configuration of the TCP transport typically involves an a priori knowledge of the deployment in order to set Initial peers for Discovery, which may not always be possible and creates difficulties when reallocating nodes of the distributed applications, as the entire discovery configuration needs to be changed. To overcome this problem, Fast DDS presents the LARGE_DATA builtin transports configuration as an approach for leveraging the Fast DDS’ TCP transport capabilities while at the same time not requiring configuration modifications when the deployment changes over time.

LARGE_DATA has been specifically designed to improve communication performance of large data samples over lossy networks. When configured, UDP transport will exclusively be used during the PDP discovery phase, taking advantage of the more reliable TCP/SHM for the remainder of the communication process. Fast DDS offers an extremely straightforward implementation for this mode through an environment variable, XML profiles or via code. Additionally, it is possible to use the builtin transports configuration options to customize the LARGE_DATA mode to better suit the specific requirements of each user.

For a video demonstration showcasing a practical example of this configuration, please refer to: Large Data communication with ROS 2.

Also, it is possible to enable TCP communication while using Discovery Server to manage Discovery.

15.1.1. Large Data Mode

The following snippets show how to configure Fast DDS DomainParticipants to run the PDP discovery phase over UDP multicast and communicate application data over a TCP Transport or Shared Memory Transport, which is called the LARGE_DATA configuration (See Managing the Builtin Transports). With this approach, applications managing large samples can benefit from transmitting their data over TCP or SHM, while at the same time have the flexibility of automatic discovery. The LARGE_DATA mode can be set using the FASTDDS_BUILTIN_TRANSPORTS environment variable (see FASTDDS_BUILTIN_TRANSPORTS), XML profiles or via code.

export FASTDDS_BUILTIN_TRANSPORTS=LARGE_DATA
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <!--
            UDP transport for PDP and SHM/TCPv4 transport for both EDP and application data
        -->
        <participant profile_name="large_data_builtin_transports" is_default_profile="true">
            <rtps>
                <builtinTransports>LARGE_DATA</builtinTransports>
            </rtps>
        </participant>
    </profiles>
</dds>
eprosima::fastdds::dds::DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;

/* Transports configuration */
// UDPv4 transport for PDP over multicast and SHM / TCPv4 transport for EDP and application data
pqos.setup_transports(eprosima::fastdds::rtps::BuiltinTransports::LARGE_DATA);

/* Create participant as usual */
eprosima::fastdds::dds::DomainParticipant* participant =
        eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(0, pqos);

Note

LARGE_DATA configuration of the builtin transports will also create a SHM transport along the UDP and TCP transports. Shared Memory will be used whenever it is possible. Manual configuration will be required if a TCP communication is required when SHM is feasible.

eprosima::fastdds::dds::DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;

/* Transports configuration */
// UDPv4 transport for PDP over multicast
auto pdp_transport = std::make_shared<eprosima::fastdds::rtps::UDPv4TransportDescriptor>();
pqos.transport().user_transports.push_back(pdp_transport);

// TCPv4 transport for EDP and application data (The listening port must to be unique for
// each participant in the same host)
constexpr uint16_t tcp_listening_port = 0;
auto data_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
data_transport->add_listener_port(tcp_listening_port);
pqos.transport().user_transports.push_back(data_transport);

pqos.transport().use_builtin_transports = false;

/* Locators */
// Define locator for PDP over multicast
eprosima::fastdds::rtps::Locator_t pdp_locator;
pdp_locator.kind = LOCATOR_KIND_UDPv4;
eprosima::fastdds::rtps::IPLocator::setIPv4(pdp_locator, "239.255.0.1");
pqos.wire_protocol().builtin.metatrafficMulticastLocatorList.push_back(pdp_locator);

// Define locator for EDP and user data
eprosima::fastdds::rtps::Locator_t tcp_locator;
tcp_locator.kind = LOCATOR_KIND_TCPv4;
eprosima::fastdds::rtps::IPLocator::setIPv4(tcp_locator, "0.0.0.0");
eprosima::fastdds::rtps::IPLocator::setPhysicalPort(tcp_locator, tcp_listening_port);
eprosima::fastdds::rtps::IPLocator::setLogicalPort(tcp_locator, tcp_listening_port);
pqos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(tcp_locator);
pqos.wire_protocol().default_unicast_locator_list.push_back(tcp_locator);

/* Create participant as usual */
eprosima::fastdds::dds::DomainParticipant* participant =
        eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(0, pqos);
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <transport_descriptors>
            <!--
                UDP transport for PDP
            -->
            <transport_descriptor>
                    <transport_id>pdp_transport</transport_id>
                    <type>UDPv4</type>
            </transport_descriptor>
            <!--
                TCP transport for both EDP and application data
            -->
            <transport_descriptor>
                <transport_id>data_transport</transport_id>
                <type>TCPv4</type>
                <!--
                    Set listening port for the transport.
                    This needs to be unique for each participant in the host
                -->
                <listening_ports>
                    <port>0</port>
                </listening_ports>
            </transport_descriptor>
        </transport_descriptors>

        <participant profile_name="udp_multicast_pdp_w_tcp_data" is_default_profile="true">
            <rtps>
                <!--
                    Set participant transports
                -->
                <userTransports>
                    <transport_id>pdp_transport</transport_id>
                    <transport_id>data_transport</transport_id>
                </userTransports>
                <useBuiltinTransports>false</useBuiltinTransports>
                <!--
                    Discovery configuration
                -->
                <builtin>
                    <!--
                        PDP over UDP multicast
                    -->
                    <metatrafficMulticastLocatorList>
                        <locator>
                            <udpv4>
                                <address>239.255.0.1</address>
                            </udpv4>
                        </locator>
                    </metatrafficMulticastLocatorList>
                    <!--
                        EDP over TCP
                    -->
                    <metatrafficUnicastLocatorList>
                        <locator>
                            <tcpv4>
                                <address>0.0.0.0</address>
                                <physical_port>12345</physical_port>
                                <port>12345</port>
                            </tcpv4>
                        </locator>
                    </metatrafficUnicastLocatorList>
                </builtin>
                <!--
                    Application data over TCP
                -->
                <defaultUnicastLocatorList>
                    <locator>
                        <tcpv4>
                            <address>0.0.0.0</address>
                            <physical_port>12345</physical_port>
                            <port>12345</port>
                        </tcpv4>
                    </locator>
                </defaultUnicastLocatorList>
            </rtps>
        </participant>
    </profiles>
</dds>

15.1.2. Large Data with configuration options

As it has been observed in Large Data Mode, LARGE_DATA builtin transports option offers an easy and efficient way to improve performance when working with large data. Nonetheless, custom configuration can help to enhance the performance even further.

Fast DDS provides configuration options to adjust the behavior of the builtin transports. This becomes particularly relevant when using the LARGE_DATA mode, as it enables increasing the maximum message size beyond 65500 KB and prevents fragmentation, leveraging the TCP and SHM transports.

All builtin transports can be configured by adjusting the following parameters:

  • max_msg_size: Message maximum size that can be sent over the transport. Sending messages larger than this size will result in fragmentation. Its maximum value is (2^32)-1 B for TCP and SHM and 65500 KB for UDP.

  • sockets_size: Size of the send and receive socket buffers. This value must be higher or equal than the max_msg_size to obtain a valid configuration. It also defines the size of the shared memory segment, calculated as twice the value set. Its maximum value is (2^32)-1 B.

  • non_blocking: If set to true, the transport will use non-blocking sockets. This can be useful to avoid blocking the application if the socket buffers are full. However, some messages will be lost. Its default value is false.

  • tcp_negotiation_timeout: It specifies the timeout duration for logical port negotiation. This parameter is useful for ensuring the availability of the logical port before data transmission, thus preventing message loss during the negotiation process. Conversely, it can delay the discovery process. The default value is 0, implying that discovery will occur as soon as possible, but the initial messages might be lost if reliability is set to BEST_EFFORT_RELIABILITY_QOS. This parameter is only valid for the LARGE_DATA mode.

Adjusting the maximum message size and the socket buffer sizes to a large enough value to accommodate the data to be sent can help improve the performance with large messages, as well as setting the transport to non-blocking mode.

In this way, it is possible to take advantage of the TCP transport to avoid fragmentation and use the non-blocking mode to avoid blocking the application when the socket buffers are full. This configuration can be used, for example, when streaming video, which will result in a significant increase in fluidity.

Note that even when using the LARGE_DATA mode within the same machine, the configuration options can prove useful for improving performance, as they affect the SHM transport. It is highly recommended to set a shared memory segment size large enough to accommodate the data to be sent. To achieve this, the sockets_size parameter must be set to a value at least half of the message size.

The following snippets show how to configure the LARGE_DATA mode:

export FASTDDS_BUILTIN_TRANSPORTS=LARGE_DATA?max_msg_size=1MB&sockets_size=1MB&non_blocking=true&tcp_negotiation_timeout=50
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
    <profiles>
        <participant profile_name="large_data_builtin_transports_options" is_default_profile="true">
            <rtps>
                <builtinTransports max_msg_size="200KB" sockets_size="200KB" non_blocking="true" tcp_negotiation_timeout="50">LARGE_DATA</builtinTransports>
            </rtps>
        </participant>
    </profiles>
</dds>
eprosima::fastdds::dds::DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;

/* Transports configuration */
// UDPv4 transport for PDP over multicast and SHM / TCPv4 transport for EDP and application data
// Message Size and Sockets sizes of 200 KB + Non-blocking send + 50ms negotiation timeout
eprosima::fastdds::rtps::BuiltinTransportsOptions large_data_options;
large_data_options.maxMessageSize = 200000;
large_data_options.sockets_buffer_size = 200000;
large_data_options.non_blocking_send = true;
large_data_options.tcp_negotiation_timeout = 50;
pqos.setup_transports(eprosima::fastdds::rtps::BuiltinTransports::LARGE_DATA, large_data_options);

/* Create participant as usual */
eprosima::fastdds::dds::DomainParticipant* participant =
        eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(0, pqos);

Note

To learn how to check and modify the default maximum system value for the socket buffers size, please refer to Finding out system maximum values.

Warning

Setting a max_msg_size value higher than 65500 KB with the DEFAULT or UDP modes will result in an error and the participant creation will fail.

15.1.3. TCP Communication with Discovery Server

Fast DDS Discovery Server consists on a client-server discovery mechanism, in which a server DomainParticipant operates as the central point of communication. It collects and processes the metatraffic sent by the client DomainParticipants, and then distributes the appropriate information among the rest of the clients. An extended description of the feature can be found at Discovery Server Settings.

To use TCP communication along with Discovery Server, both the server participant and the client participant need to use custom user transports. There exists several ways of configuring the server participant, being Fast DDS CLI the fastest solution:

It can be configured to work over a TCP transport layer by using the arguments -t and -q to set up the IP address and the TCP port, respectively. After sourcing the environment, the following command can be used to instantiate a server listening on localhost and port 12345 (see CLI).

fastdds discovery -t 127.0.0.1 -q 12345

The following snippet can be used to instantiate a server on IP 192.168.10.57 listening on port 12345.

eprosima::fastdds::dds::DomainParticipantQos qos = PARTICIPANT_QOS_DEFAULT;

// Configure the current participant as SERVER
qos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        eprosima::fastdds::rtps::DiscoveryProtocol::SERVER;

// Add custom user transport with TCP port 12345
auto data_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
data_transport->add_listener_port(12345);
qos.transport().user_transports.push_back(data_transport);

// Define the listening locator to be on interface 192.168.10.57 and port 12345
constexpr uint16_t tcp_listening_port = 12345;
eprosima::fastdds::rtps::Locator_t listening_locator;
eprosima::fastdds::rtps::IPLocator::setIPv4(listening_locator, "192.168.10.57");
eprosima::fastdds::rtps::IPLocator::setPhysicalPort(listening_locator, tcp_listening_port);
eprosima::fastdds::rtps::IPLocator::setLogicalPort(listening_locator, tcp_listening_port);
qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(listening_locator);

The following snippet can be used to instantiate a server on IP 192.168.10.57 listening on port 12345.

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>server_tcp_transport</transport_id>
                <type>TCPv4</type>
                <!--
                    Set listening port for the transport.
                    This port is where the clients will connect.
                -->
                <listening_ports>
                    <port>12345</port>
                </listening_ports>
            </transport_descriptor>
        </transport_descriptors>
        <participant profile_name="TCP_SERVER" is_default_profile="true">
            <rtps>
                <builtin>
                    <discovery_config>
                        <discoveryProtocol>SERVER</discoveryProtocol>
                    </discovery_config>
                    <metatrafficUnicastLocatorList>
                        <locator>
                            <tcpv4>
                                <address>192.168.10.57</address>
                                <port>12345</port>
                                <physical_port>12345</physical_port>
                            </tcpv4>
                        </locator>
                    </metatrafficUnicastLocatorList>
                </builtin>
                <useBuiltinTransports>false</useBuiltinTransports>
                <userTransports>
                    <transport_id>server_tcp_transport</transport_id>
                </userTransports>
            </rtps>
        </participant>
    </profiles>
</dds>

It can be configured to work over a TCP transport layer by using the argument --transport tcpv4. The IP address and the TCP port can be set up with arguments --listening-address and --listening-port, respectively. From the DiscoveryServerExample folder, the following command can be used to instantiate a server listening on localhost and port 12345.

./DiscoveryServerExample server --transport tcpv4 --listening-address 127.0.0.1 --listening-port 12345

The client participant can be configured by either using the ROS_DISCOVERY_SERVER environment variable (see ROS_DISCOVERY_SERVER) or by manually setting it.

To configure a client participant to communicate over the TCP transport layer with the ROS_DISCOVERY_SERVER environment variable, the prefix TCPv4 needs to be used. The following command can be used to configure the variable to set up a client using TCP communication and connecting to a server on localhost and port 12345.

export ROS_DISCOVERY_SERVER=TCPv4:[127.0.0.1]:12345

The following snippet can be used to instantiate a client that will try to connect to a server on IP 192.168.10.57 and port 12345, that is, the server instantiated above.

eprosima::fastdds::dds::DomainParticipantQos qos = PARTICIPANT_QOS_DEFAULT;

// Configure the current participant as SERVER
qos.wire_protocol().builtin.discovery_config.discoveryProtocol =
        eprosima::fastdds::rtps::DiscoveryProtocol::CLIENT;

// Add custom user transport with TCP port 0 (automatic port assignation)
auto data_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
data_transport->add_listener_port(0);
qos.transport().user_transports.push_back(data_transport);

// Define the server locator to be on interface 192.168.10.57 and port 12345
constexpr uint16_t server_port = 12345;
eprosima::fastdds::rtps::Locator_t server_locator;
eprosima::fastdds::rtps::IPLocator::setIPv4(server_locator, "192.168.10.57");
eprosima::fastdds::rtps::IPLocator::setPhysicalPort(server_locator, server_port);
eprosima::fastdds::rtps::IPLocator::setLogicalPort(server_locator, server_port);

// Add the server
qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(server_locator);

The following snippet can be used to instantiate a client that will try to connect to a server on IP 192.168.10.57 and port 12345, that is, the server instantiated above.

<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com">
    <profiles>
        <transport_descriptors>
            <transport_descriptor>
                    <transport_id>client_tcp_transport</transport_id>
                    <type>TCPv4</type>
                    <!--
                        Set listening port for the transport to 0.
                        This automatically assigns a port.
                    -->
                    <listening_ports>
                        <port>0</port>
                    </listening_ports>
            </transport_descriptor>
        </transport_descriptors>
        <participant profile_name="TCP_CLIENT" is_default_profile="true">
            <rtps>
                <builtin>
                    <discovery_config>
                        <discoveryProtocol>CLIENT</discoveryProtocol>
                        <discoveryServersList>
                            <!--
                                Server locator specifying where it is listening
                            -->
                            <locator>
                                <tcpv4>
                                    <address>192.168.10.57</address>
                                    <port>12345</port>
                                    <physical_port>12345</physical_port>
                                </tcpv4>
                            </locator>
                        </discoveryServersList>
                    </discovery_config>
                </builtin>
                <useBuiltinTransports>false</useBuiltinTransports>
                <userTransports>
                    <transport_id>client_tcp_transport</transport_id>
                </userTransports>
            </rtps>
        </participant>
    </profiles>
</dds>

15.2. Fast DDS over WIFI

The RTPS v2.2 standard defines the SIMPLE Discovery as the default mechanism for discovering participants in the network. One of the main features of this mechanism is the use of multicast communication in the Participant Discovery Phase (PDP). This can be a problem in cases where WiFi communication is used, since multicast is not as reliable over WiFi as it is over ethernet.

The recommended solution to this challenge is to configure an initial list of remote peers on the DomainParticipant, so that it can set unicast communication with them. This way, the use of multicast is not needed to discover these initial peers. Furthermore, if all the peers are known and configured beforehand, all multicast communication can be removed.

Alternatively, Discovery Server can be used to avoid multicast discovery. A DomainParticipant with a well-know address acts as a discovery server, providing the rest of the participants the information required to connect among them. If all the peers are known and configured beforehand, STATIC discovery can be used instead, completely avoiding the discovery phase. Use-case Well Known Network Deployments provides a detailed explanation on how to configure Fast DDS for STATIC discovery.

15.2.1. Configuring Initial Peers

A complete description of the initial peers list and its configuration can be found in Initial peers. For convenience, this example shows how to configure an initial peers list with one peer on host 192.168.10.13 with participant ID 1 in domain 0.

Note

Note that the port number used here is not arbitrary, as discovery ports are defined by the RTPS v2.2 standard. Refer to Well Known Ports to learn about these standard port numbers.

If the participant ID is not known, setting TransportDescriptorInterface maxInitialPeersRange to at least the maximum expected number of DomainParticipants will ensure discovery and communication.

DomainParticipantQos qos;

// configure an initial peer on host 192.168.10.13.
// The port number corresponds to the well-known port for metatraffic unicast
// on participant ID `1` and domain `0`.
Locator_t initial_peer;
IPLocator::setIPv4(initial_peer, "192.168.10.13");
initial_peer.port = 7412;
qos.wire_protocol().builtin.initialPeersList.push_back(initial_peer);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="initial_peers_example_profile" is_default_profile="true">
        <rtps>
            <builtin>
                <initialPeersList>
                    <locator>
                        <udpv4>
                            <address>192.168.10.13</address>
                            <port>7412</port>
                        </udpv4>
                    </locator>
                </initialPeersList>
            </builtin>
        </rtps>
    </participant>
</profiles>

15.2.2. Disabling multicast discovery

If all the peers are known and configured on the initial peer list beforehand, it is possible to disable the multicast meta traffic completely, as all DomainParticipants can communicate among them through unicast.

The complete description of the procedure to disable multicast discovery can be found at Disabling all Multicast Traffic. For convenience, however, this example shows how to disable all multicast traffic configuring one metatraffic unicast locator. Consideration should be given to the assignment of the ports in the metatrafficUnicastLocatorList, avoiding the assignment of ports that are not available or do not match the address-port listed in the intial peers list of the peer participant.

DomainParticipantQos qos;

// configure one metatraffic unicast locator on interface 192.168.10.13.
// on participant ID `1` and domain `0`.
Locator_t meta_unicast_locator;
IPLocator::setIPv4(meta_unicast_locator, "192.168.10.13");
meta_unicast_locator.port = 7412;
qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(meta_unicast_locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="initial_peers_multicast_avoidance" is_default_profile="true" >
        <rtps>
            <builtin>
                <!-- Choosing a specific unicast address -->
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>192.168.10.13</address>
                            <port>7412</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>

15.2.3. Discovery Server

During Discovery, the Participant Discovery Phase (PDP) relies on meta traffic announcements sent to multicast addresses so that all the DomainParticipants in the network can acknowledge each other. This phase is followed by a Endpoint Discovery Phase (EDP) where all the DomainParticipants use discovered unicast addresses to exchange information about their Publisher and Subscriber entities with the rest of the DomainParticipants, so that matching between entities of the same topic can occur.

Fast DDS provides a client-server discovery mechanism, in which a server DomainParticipant operates as the central point of communication. It collects and processes the metatraffic sent by the client DomainParticipants, and then distributes the appropriate information among the rest of the clients.

A complete description of the feature can be found at Discovery Server Settings. The following subsections present configurations for different discovery server use cases.

15.2.3.1. UDPv4 basic example setup

To configure the Discovery Server scenario, two types of participants are created: the server participant and the client participant. Only one parameter needs be configured in this type of implementation:

  • Server Address-port pair: Specifies the IP address and port of the machine that implements the server. Any free random port can be used. However, using RTPS standard ports is discouraged.

SERVER

DomainParticipantQos qos;

// Configure the current participant as SERVER
qos.wire_protocol().builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SERVER;

// Define the listening locator to be on interface 192.168.10.57 and port 56542
Locator_t server_locator;
IPLocator::setIPv4(server_locator, "192.168.10.57");
server_locator.port = 56542;
qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(server_locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="UDP SERVER" is_default_profile="true">
        <rtps>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>192.168.10.57</address>
                            <port>56542</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>

CLIENT

DomainParticipantQos qos;

// Configure the current participant as CLIENT
qos.wire_protocol().builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::CLIENT;

// Define a locator for the SERVER Participant on address 192.168.10.57 and port 56542
Locator_t remote_server_locator;
IPLocator::setIPv4(remote_server_locator, "192.168.10.57");
remote_server_locator.port = 56542;

// Connect to the SERVER at the previous locator
qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(remote_server_locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="UDP CLIENT" is_default_profile="true">
        <rtps>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>CLIENT</discoveryProtocol>
                    <discoveryServersList>
                        <locator>
                            <udpv4>
                                <address>192.168.10.57</address>
                                <port>56542</port>
                            </udpv4>
                        </locator>
                    </discoveryServersList>
                </discovery_config>
            </builtin>
        </rtps>
    </participant>
</profiles>
15.2.3.2. UDPv4 redundancy example

The basic setup example presents a single point of failure. That is, if the server fails the clients are not able to perform the discovery. To prevent this, several servers could be linked to each client. Then, a discovery failure only takes place if all servers fail, which is a more unlikely event.

In the example below, the values have been chosen to ensure each server has a unique unicast address-port pair. Note that several servers can share the same IP address but their port numbers should be different. Likewise, several servers can share the same port if their IP addresses are different.

Prefix

UDPv4 address-port

75.63.2D.73.76.72.63.6C.6E.74.2D.31

192.168.10.57:56542

75.63.2D.73.76.72.63.6C.6E.74.2D.32

192.168.10.60:56543

_images/ds_redundancy.svg

SERVER

// Configure first server's locator on interface 192.168.10.57 and port 56542
Locator_t server_locator_1;
IPLocator::setIPv4(server_locator_1, "192.168.10.57");
server_locator_1.port = 56542;

// Configure participant_1 as SERVER listening on the previous locator
DomainParticipantQos server_1_qos;
server_1_qos.wire_protocol().builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SERVER;
// Optional GUID
std::istringstream("75.63.2D.73.76.72.63.6C.6E.74.2D.31") >> server_1_qos.wire_protocol().prefix;
server_1_qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(server_locator_1);

// Configure second server's locator on interface 192.168.10.60 and port 56543
Locator_t server_locator_2;
IPLocator::setIPv4(server_locator_2, "192.168.10.60");
server_locator_2.port = 56543;

// Configure participant_2 as SERVER listening on the previous locator
DomainParticipantQos server_2_qos;
server_2_qos.wire_protocol().builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SERVER;
// Optional GUID
std::istringstream("75.63.2D.73.76.72.63.6C.6E.74.2D.32") >> server_2_qos.wire_protocol().prefix;
server_2_qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(server_locator_2);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="UDP SERVER 1">
        <rtps>
            <!-- Optional GUID -->
            <prefix>75.63.2D.73.76.72.63.6C.6E.74.2D.31</prefix>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>192.168.10.57</address>
                            <port>56542</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>

    <participant profile_name="UDP SERVER 2">
        <rtps>
            <!-- Optional GUID -->
            <prefix>75.63.2D.73.76.72.63.6C.6E.74.2D.32</prefix>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>192.168.10.60</address>
                            <port>56543</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>

CLIENT

// Define a locator for the first SERVER Participant
Locator_t remote_server_locator_1;
IPLocator::setIPv4(remote_server_locator_1, "192.168.10.57");
remote_server_locator_1.port = 56542;

// Define a locator for the second SERVER Participant
Locator_t remote_server_locator_2;
IPLocator::setIPv4(remote_server_locator_2, "192.168.10.60");
remote_server_locator_2.port = 56543;

// Configure the current participant as CLIENT connecting to the SERVERS at the previous locators
DomainParticipantQos client_qos;
client_qos.wire_protocol().builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::CLIENT;
client_qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(remote_server_locator_1);
client_qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(remote_server_locator_2);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="UDP CLIENT REDUNDANCY">
        <rtps>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>CLIENT</discoveryProtocol>
                    <discoveryServersList>
                        <locator>
                            <udpv4>
                                <address>192.168.10.57</address>
                                <port>56542</port>
                            </udpv4>
                        </locator>
                        <locator>
                            <udpv4>
                                <address>192.168.10.60</address>
                                <port>56543</port>
                            </udpv4>
                        </locator>
                    </discoveryServersList>
                </discovery_config>
            </builtin>
        </rtps>
    </participant>
</profiles>
15.2.3.3. UDPv4 persistency example

On Discovery Server, servers gather and maintain the information of all connected endpoints, and distribute it to the clients. In case of a server failure, all this information is lost and the server needs to recover it on restart. In the basic setup this is done starting over the Discovery process. Given that servers usually have lots of clients associated, this is very time consuming.

Alternatively, Fast DDS allows to synchronize the server’s discovery record to a file, so that the information can be loaded back into memory during the restart. This feature is enabled specifying the Discovery Protocol as BACKUP.

The record file is located on the server’s process working directory, and named following the pattern server-<GUIDPREFIX>.db (for example: server-73-65-72-76-65-72-63-6C-69-65-6E-74.db). Once the server is created, it automatically looks for this file. If it already exists, its contents are loaded, avoiding the need of re-discovering the clients. To make a fresh restart, any such backup file must be removed or renamed before launching the server.

15.2.3.4. UDPv4 partitioning using servers

Server association can be seen as another isolation mechanism besides Domains and Partitions. Clients that do not share a server cannot see each other and belong to isolated server networks. For example, in the following figure, client 1 and client 2 cannot communicate even if they are on the same physical network and Domain.

_images/ds_partition.svg

Clients cannot see each other due to server isolation

However, it is possible to connect server isolated networks very much as physical networks can be connected through routers:

  • Option 1: Connecting the clients to several servers, so that the clients belong to several networks.

  • Option 2: Connecting one server to another, so that the networks are linked together.

  • Option 3: Create a new server linked to the servers to which the clients are connected.

Options 1 and 2 can only be implemented by modifying QoS values or XML configuration files beforehand. In this regard they match the domain and partition strategy. Option 3, however, can be implemented at runtime, when the isolated networks are already up and running.

_images/ds_partition_link.svg
15.2.3.4.1. Option 1

Connect each client to both servers. This case matches the redundancy use case already introduced.

15.2.3.4.2. Option 2

Connect one server to the other. This means configuring one of the servers to act as a client of the other.

Consider two servers, each one managing an isolated network:

Network

Prefix

UDPv4 address

A

75.63.2D.73.76.72.63.6C.6E.74.2D.31

192.168.10.60:56543

B

75.63.2D.73.76.72.63.6C.6E.74.2D.32

192.168.10.57:56542

In order to communicate both networks we can set server A to act as a client of server B:

DomainParticipantQos qos;

// Configure current Participant as SERVER on address 192.168.10.60
Locator_t server_locator;
IPLocator::setIPv4(server_locator, "192.168.10.60");
server_locator.port = 56543;

qos.wire_protocol().builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SERVER;
// Optional GUID
std::istringstream("75.63.2D.73.76.72.63.6C.6E.74.2D.31") >> qos.wire_protocol().prefix;
qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(server_locator);

// Add the connection attributes to the remote server.
Locator_t remote_server_locator;
IPLocator::setIPv4(remote_server_locator, "192.168.10.57");
remote_server_locator.port = 56542;

qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(remote_server_locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="UDP SERVER A">
        <rtps>
            <!-- Optional GUID -->
            <prefix>75.63.2D.73.76.72.63.6C.6E.74.2D.31</prefix>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                    <discoveryServersList>
                        <locator>
                            <udpv4>
                                <address>192.168.10.57</address>
                                <port>56542</port>
                            </udpv4>
                        </locator>
                    </discoveryServersList>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>192.168.10.60</address>
                            <port>56543</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>
15.2.3.4.3. Option 3

Create a new server linked to the servers to which the clients are connected.

Consider two servers (A and B), each one managing an isolated network, and a third server (C) that will be used to connect the first two:

Server

Prefix

UDPv4 address

A

75.63.2D.73.76.72.63.6C.6E.74.2D.31

192.168.10.60:56543

B

75.63.2D.73.76.72.63.6C.6E.74.2D.32

192.168.10.57:56542

C

75.63.2D.73.76.72.63.6C.6E.74.2D.33

192.168.10.54:56541

In order to communicate both networks we can setup server C to act as client of servers A and B as follows:

DomainParticipantQos qos;

// Configure current Participant as SERVER on address 192.168.10.60
Locator_t server_locator;
IPLocator::setIPv4(server_locator, "192.168.10.54");
server_locator.port = 56541;

qos.wire_protocol().builtin.discovery_config.discoveryProtocol = DiscoveryProtocol::SERVER;
// Optional GUID
std::istringstream("75.63.2D.73.76.72.63.6C.6E.74.2D.33") >> qos.wire_protocol().prefix;
qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(server_locator);

// Add the connection attributes to the remote server A.
Locator_t remote_server_locator_A;
IPLocator::setIPv4(remote_server_locator_A, "192.168.10.60");
remote_server_locator_A.port = 56543;

qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(remote_server_locator_A);

// Add the connection attributes to the remote server B.
Locator_t remote_server_locator_B;
IPLocator::setIPv4(remote_server_locator_B, "192.168.10.57");
remote_server_locator_B.port = 56542;

qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(remote_server_locator_B);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="UDP SERVER C">
        <rtps>
            <!-- Optional GUID -->
            <prefix>75.63.2D.73.76.72.63.6C.6E.74.2D.33</prefix>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                    <discoveryServersList>
                        <locator>
                            <udpv4>
                                <address>192.168.10.57</address>
                                <port>56542</port>
                            </udpv4>
                        </locator>
                        <locator>
                            <udpv4>
                                <address>192.168.10.60</address>
                                <port>56543</port>
                            </udpv4>
                        </locator>
                    </discoveryServersList>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>192.168.10.54</address>
                            <port>56541</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
</profiles>

Note

GUID Prefixes are used in these examples to identify the servers and help to understand each scenario. However, they are not mandatory and can be omitted. Note that in the clients configuration, the GUID Prefix is always missing, as it is not needed in order to connect to the servers.

15.3. Well Known Network Deployments

It is often the case in industrial deployments, such as productions lines, that the entire network topology (hosts, IP addresses, etc.) is known beforehand. Such scenarios are perfect candidates for Fast DDS STATIC Discovery mechanism, which drastically reduces the middleware setup time (time until all the entities are ready for information exchange), while at the same time limits the connections to those strictly necessary.

Knowing the complete network topology allows to:

15.3.1. Peer-to-Peer Participant Discovery Phase

The SIMPLE PDP discovery phase entails the DomainParticipants sending periodic PDP announcements over multicast, and answering to the announcements received from remote DomainParticipants. As a result, the number of PDP connections grows quadratically with the number of DomainParticipants, resulting in a large amount of meta traffic on the network.

However, if all DomainParticipants are known beforehand, they can be configured to send their announcements only to the unicast addresses of their peers. This is done by specifying a list of peer addresses, and by disabling the participant multicast announcements. As an additional advantage, with this method only the peers configured on the list are known to the DomainParticipant, allowing to arrange which participant will communicate with which. This reduces the amount of meta traffic if not all the DomainParticipants need to be aware of all the rest of the remote participants present in the network.

Use-case Fast DDS over WIFI provides a detailed explanation on how to configure Fast DDS for such cases.

15.3.2. STATIC Endpoint Discovery Phase

Users can manually configure which Publisher and Subscriber match with each other, so they can start sharing user data right away, avoiding the EDP phase.

A complete description of the feature can be found at STATIC Discovery Settings. There is also a fully functional hello world example implementing STATIC EDP in the examples/cpp/static_edp_discovery folder.

The following subsections present an example configuration where a Publisher in Topic HelloWorldTopic from DomainParticipant HelloWorldPublisher is matched with a Subscriber from DomainParticipant HelloWorldSubscriber.

15.3.2.1. Create STATIC discovery XML files

HelloWorldPublisher.xml

<staticdiscovery>
    <participant>
        <name>HelloWorldPublisher</name>
        <writer>
            <userId>1</userId>
            <entityID>2</entityID>
            <topicName>HelloWorldTopic</topicName>
            <topicDataType>HelloWorld</topicDataType>
        </writer>
    </participant>
</staticdiscovery>

HelloWorldSubscriber.xml

<staticdiscovery>
    <participant>
        <name>HelloWorldSubscriber</name>
        <reader>
            <userId>3</userId>
            <entityID>4</entityID>
            <topicName>HelloWorldTopic</topicName>
            <topicDataType>HelloWorld</topicDataType>
        </reader>
    </participant>
</staticdiscovery>
15.3.2.2. Create entities and load STATIC discovery XML files

When creating the entities, the local writer/reader attributes must match those defined in the STATIC discovery XML file loaded by the remote entity.

PUBLISHER
// Participant configuration
DomainParticipantQos participant_qos;
participant_qos.name("HelloWorldPublisher");
participant_qos.wire_protocol().builtin.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol = false;
participant_qos.wire_protocol().builtin.discovery_config.use_STATIC_EndpointDiscoveryProtocol = true;
participant_qos.wire_protocol().builtin.discovery_config.static_edp_xml_config("HelloWorldSubscriber.xml");

// DataWriter configuration
DataWriterQos writer_qos;
writer_qos.endpoint().user_defined_id = 1;
writer_qos.endpoint().entity_id = 2;

// Create the DomainParticipant
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, participant_qos);
if (nullptr == participant)
{
    // Error
    return;
}

// Create the Publisher
Publisher* publisher =
        participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (nullptr == publisher)
{
    // Error
    return;
}

// Create the Topic with the appropriate name and data type
std::string topic_name = "HelloWorldTopic";
std::string data_type = "HelloWorld";
Topic* topic =
        participant->create_topic(topic_name, data_type, TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Create the DataWriter
DataWriter* writer =
        publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == writer)
{
    // Error
    return;
}
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_static_pub">
        <rtps>
            <name>HelloWorldPublisher</name>
            <builtin>
                <discovery_config>
                    <EDP>STATIC</EDP>
                    <static_edp_xml_config>file://HelloWorldSubscriber.xml</static_edp_xml_config>
                </discovery_config>
            </builtin>
        </rtps>
    </participant>

    <data_writer profile_name="uc_publisher_xml_conf_static_discovery">
        <userDefinedID>1</userDefinedID>
        <entityID>2</entityID>
    </data_writer>
</profiles>
SUBSCRIBER
// Participant configuration
DomainParticipantQos participant_qos;
participant_qos.name("HelloWorldSubscriber");
participant_qos.wire_protocol().builtin.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol = false;
participant_qos.wire_protocol().builtin.discovery_config.use_STATIC_EndpointDiscoveryProtocol = true;
participant_qos.wire_protocol().builtin.discovery_config.static_edp_xml_config("HelloWorldPublisher.xml");

// DataWriter configuration
DataWriterQos writer_qos;
writer_qos.endpoint().user_defined_id = 3;
writer_qos.endpoint().entity_id = 4;

// Create the DomainParticipant
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, participant_qos);
if (nullptr == participant)
{
    // Error
    return;
}

// Create the Subscriber
Subscriber* subscriber =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber)
{
    // Error
    return;
}

// Create the Topic with the appropriate name and data type
std::string topic_name = "HelloWorldTopic";
std::string data_type = "HelloWorld";
Topic* topic =
        participant->create_topic(topic_name, data_type, TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
    // Error
    return;
}

// Create the DataReader
DataReader* reader =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == reader)
{
    // Error
    return;
}
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_static_sub">
        <rtps>
            <name>HelloWorldSubscriber</name>
            <builtin>
                <discovery_config>
                    <static_edp_xml_config>file://HelloWorldPublisher.xml</static_edp_xml_config>
                </discovery_config>
            </builtin>
        </rtps>
    </participant>

    <data_reader profile_name="uc_subscriber_xml_conf_static_discovery">
        <userDefinedID>3</userDefinedID>
        <entityID>4</entityID>
    </data_reader>
</profiles>

15.4. Large Data Rates

When the amount of data exchanged between a Publisher and a Subscriber is large, some extra configuration may be required to compensate for side effects on the network and CPU load. This large amount of data can be a result of the data types being large, a high message rate, or a combination of both.

In this scenario, several approaches can be considered depending on the problem:

  • For the cases in which the data samples are large (in the order of MB) such as transmitting raw video frames, point clouds, images, etc. between different hosts, TCP based communications may yield better reception rates with lower message loss, specially in the cases where a best effort transport layer is more susceptible to data loss, such as WiFi. To tackle these cases, Large Data mode and Fast DDS over TCP documents several ways to configure Fast DDS to communicate over TCP.

  • Network packages could be dropped because the transmitted amount of data fills the socket buffer before it can be processed. The solution is to increase the buffers size.

  • It is also possible to limit the rate at which the Publisher sends data using Flow Controllers, in order to limit the effect of message bursts, and avoid to flood the Subscribers faster than they can process the messages.

  • On RELIABLE_RELIABILITY_QOS mode, the overall message rate can be affected due to the retransmission of lost packets. Selecting the Heartbeat period allows to tune between increased meta traffic or faster response to lost packets. See Tuning Heartbeat Period.

  • Also on RELIABLE_RELIABILITY_QOS mode, with high message rates, the history of the DataWriter can be filled up, blocking the publication of new messages. A non-strict reliable mode can be configured to avoid this blocking, at the cost of potentially losing some messages on some of the Subscribers.

Warning

eProsima Fast DDS defines a conservative default message size of 64kB, which roughly corresponds to TCP and UDP payload sizes. If the topic data is bigger, it will automatically be fragmented into several transport packets.

Warning

The loss of a fragment means the loss of the entire message. This has the most impact on BEST_EFFORT_RELIABILITY_QOS mode, where the message loss probability increases with the number of fragments

15.4.1. Increasing socket buffers size

In high rate scenarios or large data scenarios, network packages can be dropped because the transmitted amount of data fills the socket buffer before it can be processed. Using RELIABLE_RELIABILITY_QOS mode, Fast DDS will try to recover lost samples, but with the penalty of retransmission. With BEST_EFFORT_RELIABILITY_QOS mode, samples will be definitely lost.

By default eProsima Fast DDS creates socket buffers with the system default size. However, these sizes can be modified using the DomainParticipantQos, as shown in the example below.

DomainParticipantQos participant_qos;

// Increase the sending buffer size
participant_qos.transport().send_socket_buffer_size = 1048576;

// Increase the receiving buffer size
participant_qos.transport().listen_socket_buffer_size = 4194304;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_xml_profile_qos_socketbuffers">
        <rtps>
            <sendSocketBufferSize>1048576</sendSocketBufferSize>
            <listenSocketBufferSize>4194304</listenSocketBufferSize>
        </rtps>
    </participant>
</profiles>
15.4.1.1. Finding out system maximum values

Operating systems set a maximum value for socket buffer sizes. If the buffer sizes are tuned with DomainParticipantQos, the values set cannot exceed the maximum value of the system.

15.4.1.1.1. Linux

The maximum buffer size values can be retrieved with the command sysctl. For socket buffers used to send data, use the following command:

$> sudo sysctl -a | grep net.core.wmem_max
net.core.wmem_max = 1048576

For socket buffers used to receive data the command is:

$> sudo sysctl -a | grep net.core.rmem_max
net.core.rmem_max = 4194304

However, these maximum values are also configurable and can be increased if needed. The following command increases the maximum buffer size of sending sockets:

$> sudo sysctl -w net.core.wmem_max=12582912

For receiving sockets, the command is:

$> sudo sysctl -w net.core.rmem_max=12582912
15.4.1.1.2. Windows

The following command changes the maximum buffer size of sending sockets:

C:\> reg add HKLM\SYSTEM\CurrentControlSet\services\AFD\Parameters /v DefaultSendWindow /t REG_DWORD /d 12582912

For receiving sockets, the command is:

C:\> reg add HKLM\SYSTEM\CurrentControlSet\services\AFD\Parameters /v DefaultReceiveWindow /t REG_DWORD /d 12582912

15.4.2. Increasing the Transmit Queue Length of an interface (Linux only)

The Transmit Queue Length (txqueuelen) is a TCP/UDP/IP stack network interface value. This value sets the number of packets allowed per kernel transmit queue of a network interface device. By default, the txqueuelen value for Ethernet interfaces is set to 1000 in Linux. This value is adequate for most Gigabit network devices. However, in some specific cases, the txqueuelen setting should be increased to avoid overflows that drop packets. Similarly, choosing a value that is too large can cause added overhead resulting in higher network latencies.

Note that this information only applies to the sending side, and not the receiving side. Also increasing the txqueuelen should go together with increasing the buffer sizes of the UDP and/or TCP buffers. (this must be applied for both the sending and receiving sides).

The settings for a specific network adapter can be viewed using the one of the following commands:

ip link show ${interface}
ifconfig ${interface}

This will display the configuration of the adapter, and among the parameters the txqueuelen. This parameter can be a value between 1000 and 20000.

Important

If the ip command is used, the Transmit Queue Length parameter is called qlen.

The txqueuelen can be modified for the current session using either the ifconfig or ip commands. However, take into account that after rebooting the default values will be configured again.

ip link set txqueuelen ${value} dev ${interface}
ifconfig ${interface} txqueuelen ${size}

15.4.3. Flow Controllers

eProsima Fast DDS provides a mechanism to limit the rate at which the data is sent by a DataWriter. These controllers should be registered on the creation of the DomainParticipant using FlowControllersQos, and then referenced by the DataWriter whose traffic is to be controlled:

  • User DataWriters: The flow controller should be assigned through PublishModeQosPolicy to regulate the transmission of application data.

  • Built-in DataWriters: The flow controller can be configured to control meta-traffic generated by built-in DataWriters responsible for PDP and EDP (DiscoveryProtocol); WLP (LivelinessQosPolicy), and TypeLookupService (TypeObject representation). This allows for fine-grained control over discovery and built-in traffic. The flow controller should be assigned through WireProtocolConfigQos.

A new thread is spawned the first time a flow controller is referenced by an asynchronous DataWriter. This thread will be responsible for arbitrating the network output of the samples being transmitted by all the DataWriters referencing the same flow controller.

Flow controllers should be given a name so they can later on be referenced by the DataWriters. A default, unlimited, FIFO flow controller is always available with name FASTDDS_FLOW_CONTROLLER_DEFAULT.

15.4.3.1. Scheduling policy

There are different kinds of flow controllers, depending on the scheduling policy used. All of them will limit the number of bytes sent to the network to no more than max_bytes_per_period bytes during period_ms milliseconds. They only differ in the way they decide the order in which the samples are sent.

  • FIFO will output samples on a first come, first served order.

  • ROUND_ROBIN will output one sample from each DataWriter in circular order.

  • HIGH_PRIORITY will output samples from DataWriters with the highest priority first. The priority of a DataWriter is configured using property fastdds.sfc.priority. Allowed values are from -10 (highest priority) to 10 (lowest priority). If the property is not present, it will be set to the lowest priority. Samples for DataWriters with the same priority are handled with FIFO order.

  • PRIORITY_WITH_RESERVATION works as the previous one, but allows the DataWriters to reserve part of the output bandwidth. This is done with the property fastdds.sfc.bandwidth_reservation. Allowed values are from 0 to 100, and express a percentage of the total flow controller limit. If the property is not present, it will be set to 0 (no bandwidth is reserved for the DataWriter). After the reserved bandwidth has been consumed, the rest of the samples will be handled with the rules of HIGH_PRIORITY.

15.4.3.2. Example configuration
// Limit to 300kb per second.
static const char* flow_controller_name = "example_flow_controller";
auto flow_control_300k_per_sec = std::make_shared<eprosima::fastdds::rtps::FlowControllerDescriptor>();
flow_control_300k_per_sec->name = flow_controller_name;
flow_control_300k_per_sec->scheduler = eprosima::fastdds::rtps::FlowControllerSchedulerPolicy::FIFO;
flow_control_300k_per_sec->max_bytes_per_period = 300 * 1000;
flow_control_300k_per_sec->period_ms = 1000;

// [OPTIONAL] Configure sender thread settings
flow_control_300k_per_sec->sender_thread = eprosima::fastdds::rtps::ThreadSettings{-1, 0, 0, -1};

// Register flow controller on participant
DomainParticipantQos participant_qos;
participant_qos.flow_controllers().push_back(flow_control_300k_per_sec);

// [OPTIONAL] Link builtin writers to any of the registered flow controllers
participant_qos.wire_protocol().builtin.flow_controller_name = "example_flow_controller";

// .... create participant and publisher

// Link writer to the registered flow controller.
// Note that ASYNCHRONOUS_PUBLISH_MODE must be used
DataWriterQos qos;
qos.publish_mode().kind = ASYNCHRONOUS_PUBLISH_MODE;
qos.publish_mode().flow_controller_name = flow_controller_name;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_qos_flowcontroller">
        <rtps>
            <flow_controller_descriptor_list>
                <flow_controller_descriptor>
                    <name>example_flow_controller</name>
                    <scheduler>FIFO</scheduler>
                    <max_bytes_per_period>4096</max_bytes_per_period>
                    <period_ms>500</period_ms>
                    <sender_thread>
                        <scheduling_policy>-1</scheduling_policy>
                        <priority>0</priority>
                        <affinity>0</affinity>
                        <stack_size>-1</stack_size>
                    </sender_thread>
                </flow_controller_descriptor>
            </flow_controller_descriptor_list>

            <builtin> <!-- Optional use of flow controller for participant's meta traffic-->
                <flow_controller_name>example_flow_controller</flow_controller_name>
            </builtin>
        </rtps>
    </participant>

    <data_writer profile_name="writer_profile_qos_flowcontroller">
        <qos>
            <publishMode>
                <kind>ASYNCHRONOUS</kind>
                <flow_controller_name>example_flow_controller</flow_controller_name>
            </publishMode>
        </qos>
    </data_writer>
</profiles>

Warning

Specifying a flow controller with a size smaller than the transport buffer size can cause the messages to never be sent.

15.4.4. Tuning Heartbeat Period

On RELIABLE_RELIABILITY_QOS (ReliabilityQosPolicy), RTPS protocol can detect which messages have been lost and retransmit them. This mechanism is based on meta-traffic information exchanged between DataWriters and DataReaders, namely, Heartbeat and Ack/Nack messages.

A smaller Heartbeat period increases the CPU and network overhead, but speeds up the system response when a piece of data is lost. Therefore, users can customize the Heartbeat period to match their needs. This can be done with the DataWriterQos.

DataWriterQos qos;
qos.reliable_writer_qos().times.heartbeat_period.seconds = 0;
qos.reliable_writer_qos().times.heartbeat_period.nanosec = 500000000;     //500 ms

15.4.5. Using Non-strict Reliability

When HistoryQosPolicyKind is set as KEEP_ALL_HISTORY_QOS, all samples have to be received (and acknowledged) by all subscribers before they can be overridden by the DataWriter. If the message rate is high and the network is not reliable (i.e., lots of packets get lost), the history of the DataWriter can be filled up, blocking the publication of new messages until any of the old messages is acknowledged by all subscribers.

If this strictness is not needed, HistoryQosPolicyKind can be set as KEEP_LAST_HISTORY_QOS. In this case, when the history of the DataWriter is full, the oldest message that has not been fully acknowledged yet is overridden with the new one. If any subscriber did not receive the discarded message, the publisher will send a GAP message to inform the subscriber that the message is lost forever.

15.4.6. Practical Examples

15.4.6.1. Example: Sending a large file

Consider the following scenario:

  • A Publisher needs to send a file with a size of 9.9 MB.

  • The Publisher and Subscriber are connected through a network with a bandwidth of 100 MB/s

With a fragment size of 64 kB, the Publisher has to send about 1100 fragments to send the whole file. A possible configuration for this scenario could be:

  • Using RELIABLE_RELIABILITY_QOS, since a losing a single fragment would mean the loss of the complete file.

  • Decreasing the heartbeat period, in order to increase the reactivity of the Publisher.

  • Limiting the data rate using a Flow Controller, to avoid this transmission cannibalizing the whole bandwidth. A reasonable rate for this application could be 5 MB/s, which represents only 5% of the total bandwidth.

Note

Using Shared Memory Transport the only limit to the fragment size is the available memory. Therefore, all fragmentation can be avoided in SHM by increasing the size of the shared buffers.

15.4.6.2. Example: Video streaming

In this scenario, the application transmits a video stream between a Publisher and a Subscriber, at 50 fps. In real-time audio or video transmissions, it is usually preferred to have a high stable datarate feed, even at the cost of losing some samples. Losing one or two samples per second at 50 fps is more acceptable than freezing the video waiting for the retransmission of lost samples. Therefore, in this case BEST_EFFORT_RELIABILITY_QOS can be appropriate.

15.5. Topics with many subscribers

By default, every time a DataWriter publishes a data change on a Topic, it sends a unicast message for every DataReader that is subscribed to the Topic. If there are several DataReaders subscribed, it is recommendable to use multicast instead of unicast. By doing so, only one network package will be sent for each sample. This will improve both CPU and network usage.

This solution can be implemented with UDP Transport or Shared Memory Transport (SHM). SHM transport is multicast by default, but is only available between DataWriters and DataReaders on the same machine. UDP transport needs some extra configuration. The example below shows how to set a DataReaderQos to configure a DataReader to use a multicast transport on UDP. More information about configuring local and remote locators on endpoints can be found in RTPSEndpointQos.

Note

Multicast over UDP can be problematic on some scenarios, mainly WiFi and complex networks with multiple network links.

DataReaderQos qos;

// Add new multicast locator with IP 239.255.0.4 and port 7900
eprosima::fastdds::rtps::Locator_t new_multicast_locator;
eprosima::fastdds::rtps::IPLocator::setIPv4(new_multicast_locator, "239.255.0.4");
new_multicast_locator.port = 7900;
qos.endpoint().multicast_locator_list.push_back(new_multicast_locator);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <data_reader profile_name="reader_xml_conf_multicast_locators_profile">
        <multicastLocatorList>
            <locator>
                <udpv4>
                    <address>239.255.0.4</address>
                    <port>7900</port>
                </udpv4>
            </locator>
        </multicastLocatorList>
    </data_reader>
</profiles>

15.6. Real-time behavior

Real-time applications have very tight constraints on data processing times. In order to comply with these constraints, Fast DDS can be configured to guarantee responses within a specified time. This is achieved with the following restraints:

  • Allocating all the required memory during entity initialization, so that all the data processing tasks are heap allocation free (see Tuning allocations).

  • Returning from blocking functions if the provided timeout is reached (see Non-blocking calls).

This section explains how to configure Fast DDS to achieve this behavior.

15.6.1. Tuning allocations

Allocating and deallocating memory implies some non-deterministic time consuming operations. Therefore, most real-time systems need to operate in a way that all dynamic memory is allocated during the application initialization, avoiding memory management operations in the main loop.

If users provide maximum sizes for the data and collections that Fast DDS keeps internally, memory for these data and collections can be preallocated during entity initialization. In order to choose the correct size values, users must be aware of the topology of the whole domain. Specifically, the number of DomainParticipants, DataWriters, and DataReaders must be known when setting their configuration.

The following sections describe how to configure allocations to be done during the initialization of the entities. Although some examples are provided on each section as reference, there is also a complete example use case.

15.6.1.1. Parameters on the participant

Every DomainParticipant holds an internal collection with information about every local and remote peer DomainParticipants that has been discovered. This information includes, among other things:

  • A nested collection with information of every DataWriter announced on the peer DomainParticipant.

  • A nested collection with information of every DataReader announced on the peer DomainParticipant.

  • Custom data configured by the user on the peer DomainParticipant, namely, UserDataQosPolicy, PartitionQosPolicy, and PropertyPolicyQos.

By default, these collections are fully dynamic, meaning that new memory is allocated when a new DomainParticipant, DataWriter, or DataReader is discovered. Likewise, the mentioned custom configuration data parameters have an arbitrary size. By default, the memory for these parameters is allocated when the peer DomainParticipant announces their value.

However, DomainParticipantQos has a member function allocation(), of type ParticipantResourceLimitsQos, that allows configuring maximum sizes for these collections and parameters, so that all the required memory can be preallocated during the initialization of the DomainParticipant.

15.6.1.1.1. Limiting the number of discovered entities

ParticipantResourceLimitsQos provides three data members to configure the allocation behavior of discovered entities:

  • participants configures the allocation of the collection of discovered DomainParticipants.

  • readers configures the allocation of the collection of DataWriters within each discovered DomainParticipant.

  • writers configures the allocation of the collection of DataReaders within each discovered DomainParticipant.

By default, a full dynamic behavior is used. Using these members, however, it is easy to configure the collections to be preallocated during initialization, setting them to a static maximum expected value, as shown in the example below. Please, refer to ResourceLimitedContainerConfig for a complete description of additional configuration alternatives given by these data members.

DomainParticipantQos qos;

// Fix the size of discovered participants to 3
// This will effectively preallocate the memory during initialization
qos.allocation().participants =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(3u);

// Fix the size of discovered DataWriters to 1 per DomainParticipant
// Fix the size of discovered DataReaders to 3 per DomainParticipant
// This will effectively preallocate the memory during initialization
qos.allocation().writers =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(1u);
qos.allocation().readers =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(3u);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_qos_entity_resource_limit">
        <rtps>
            <allocation>
                <!-- Limit to 3 participants -->
                <total_participants>
                    <initial>3</initial>
                    <maximum>3</maximum>
                    <increment>0</increment>
                </total_participants>

                <!-- Limit to 3 readers per participant -->
                <total_readers>
                    <initial>3</initial>
                    <maximum>3</maximum>
                    <increment>0</increment>
                </total_readers>

                <!-- Limit to 1 writer per participant -->
                <total_writers>
                    <initial>1</initial>
                    <maximum>1</maximum>
                    <increment>0</increment>
                </total_writers>
            </allocation>
        </rtps>
    </participant>
</profiles>

Warning

Configuring a collection as fixed in size effectively limits the number of peer entities that can be discovered. Once the configured limit is reached, any new entity will be ignored. In the given example, if a fourth peer DomainParticipant appears, it will not be discovered, as the collection of discovered DomainParticipants is already full.

15.6.1.1.2. Limiting the size of custom parameters

data_limits inside ParticipantResourceLimitsQos provides three data members to configure the allocation behavior of custom parameters:

If these sizes are configured to something different than zero, enough memory will be allocated for them for each participant and endpoint. A value of zero implies no size limitation, and memory will be dynamically allocated as needed. By default, a full dynamic behavior is used.

content_filter inside ParticipantResourceLimitsQos provides members to configure the allocation behavior of content filter discovery information:

  • expression_initial_size sets the preallocated size of the filter expression.

  • expression_parameters controls the allocation behavior for the list of expression parameters. Refer to ResourceLimitedContainerConfig for a complete description of the alternatives. Receiving information about a content filter with more parameters than the maximum configured here, will make the filtering happen on the reader side.

DomainParticipantQos qos;

// Fix the size of the complete user data field to 256 octets
qos.allocation().data_limits.max_user_data = 256u;
// Fix the size of the complete partitions field to 256 octets
qos.allocation().data_limits.max_partitions = 256u;
// Fix the size of the complete properties field to 512 octets
qos.allocation().data_limits.max_properties = 512u;
// Set the preallocated filter expression size to 512 characters
qos.allocation().content_filter.expression_initial_size = 512u;
// Set the maximum number of expression parameters to 4 and its allocation configuration to fixed size
qos.allocation().content_filter.expression_parameters =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(4u);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_qos_parameter_resource_limit">
        <rtps>
            <allocation>
                <max_partitions>256</max_partitions>
                <max_user_data>256</max_user_data>
                <max_properties>512</max_properties>

                <!-- content_filter cannot be configured using XML (yet) -->
            </allocation>
        </rtps>
    </participant>
</profiles>

Warning

If the data fields announced by the remote peer do not fit on the preallocated memory, an error will be triggered during the processing of the announcement message. This usually means that the discovery messages of a remote peer with too large data fields will be discarded, i.e., peers with too large data fields will not be discovered.

15.6.1.2. Parameters on the DataWriter

Every DataWriter holds internal collections with information about every DataReader to which it matches. By default, these collections are fully dynamic, meaning that new memory is allocated when a new DataReader is matched. However, DataWriterQos has a data member writer_resource_limits(), of type WriterResourceLimitsQos, that allows configuring the memory allocation behavior on the DataWriter.

WriterResourceLimitsQos provides data members matched_subscriber_allocation and reader_filters_allocation of type ResourceLimitedContainerConfig that allow configuring the maximum expected size of the collection of matched DataReader, and the collection of writer side content filters, so they can be preallocated during the initialization of the DataWriter, as shown in the example below. Please, refer to ResourceLimitedContainerConfig for a complete description of additional configuration alternatives given by these data members.

DataWriterQos qos;

// Fix the size of matched DataReaders to 3
// This will effectively preallocate the memory during initialization
qos.writer_resource_limits().matched_subscriber_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(3u);
// Fix the size of writer side content filters to 1
// This will effectively preallocate the memory during initialization
qos.writer_resource_limits().reader_filters_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(1u);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <data_writer profile_name="writer_profile_qos_resource_limit">
        <!-- Limit to 3 matching readers -->
        <matchedSubscribersAllocation>
            <initial>3</initial>
            <maximum>3</maximum>
            <increment>0</increment>
        </matchedSubscribersAllocation>

        <!-- reader_filters_allocation cannot be configured using XML (yet) -->
    </data_writer>
</profiles>

Warning

Configuring the collection of matched DataReaders as fixed in size effectively limits the number of DataReaders to be matched. Once the configured limit is reached, any new DataReader will be ignored. In the given example, if a fourth (potentially matching) DataReader appears, it will not be matched, as the collection is already full.

15.6.1.3. Parameters on the DataReader

Every DataReader holds an internal collection with information about every ReaderResourceLimitsQos to which it matches. By default, this collection is fully dynamic, meaning that new memory is allocated when a new DataWriter is matched. However, DataReaderQos has a data member reader_resource_limits(), of type ReaderResourceLimitsQos, that allows configuring the memory allocation behavior on the DataReader.

ReaderResourceLimitsQos provides a data member matched_publisher_allocation of type ResourceLimitedContainerConfig that allows configuring the maximum expected size of the collection of matched DataWriters, so that it can be preallocated during the initialization of the DataReader, as shown in the example below. Please, refer to ResourceLimitedContainerConfig for a complete description of additional configuration alternatives given by this data member.

DataReaderQos qos;

// Fix the size of matched DataWriters to 1
// This will effectively preallocate the memory during initialization
qos.reader_resource_limits().matched_publisher_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(1u);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <data_reader profile_name="reader_profile_qos_resource_limit">
        <!-- Limit to 1 matching writer -->
        <matchedPublishersAllocation>
            <initial>1</initial>
            <maximum>1</maximum>
            <increment>0</increment>
        </matchedPublishersAllocation>
    </data_reader>
</profiles>

Warning

Configuring the collection of matched DataWriters as fixed in size effectively limits the number of DataWriters to be matched. Once the configured limit is reached, any new DataWriter will be ignored. In the given example, if a fourth (potentially matching) DataWriter appears, it will not be matched, as the collection is already full.

15.6.1.4. Full example

Given a system with the following topology:

Allocation tuning example topology

Participant P1

Participant P2

Participant P3

Topic 1 publisher

Topic 1 subscriber

Topic 2 subscriber

Topic 1 subscriber

Topic 2 publisher

Topic 1 subscriber

Topic 2 subscriber

  • The total number of DomainParticipants is 3.

  • The maximum number of DataWriters per DomainParticipant is 1

  • The maximum number of DataReaders per DomainParticipant is 2.

  • The DataWriter for topic 1 matches with 3 DataReaders.

  • The DataWriter for topic 2 matches with 2 DataReaders.

  • All the DataReaders match exactly with 1 DataWriter.

We will assume that content filtering is not being used, and will also limit the size of the parameters:

The following piece of code shows the set of parameters needed for the use case depicted in this example.

// DomainParticipant configuration
//////////////////////////////////
DomainParticipantQos participant_qos;

// We know we have 3 participants on the domain
participant_qos.allocation().participants =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(3u);
// We know we have at most 2 readers on each participant
participant_qos.allocation().readers =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(2u);
// We know we have at most 1 writer on each participant
participant_qos.allocation().writers =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(1u);

// We know the maximum size of partition data
participant_qos.allocation().data_limits.max_partitions = 256u;
// We know the maximum size of user data
participant_qos.allocation().data_limits.max_user_data = 256u;
// We know the maximum size of properties data
participant_qos.allocation().data_limits.max_properties = 512u;

// Content filtering is not being used
participant_qos.allocation().content_filter.expression_initial_size = 0u;
participant_qos.allocation().content_filter.expression_parameters =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(0u);

// DataWriter configuration for Topic 1
///////////////////////////////////////
DataWriterQos writer1_qos;

// We know we will only have three matching subscribers, and no content filters
writer1_qos.writer_resource_limits().matched_subscriber_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(3u);
writer1_qos.writer_resource_limits().reader_filters_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(0u);

// DataWriter configuration for Topic 2
///////////////////////////////////////
DataWriterQos writer2_qos;

// We know we will only have two matching subscribers
writer2_qos.writer_resource_limits().matched_subscriber_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(2u);
writer2_qos.writer_resource_limits().reader_filters_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(0u);


// DataReader configuration for both Topics
///////////////////////////////////////////
DataReaderQos reader_qos;

// We know we will only have one matching publisher
reader_qos.reader_resource_limits().matched_publisher_allocation =
        eprosima::fastdds::ResourceLimitedContainerConfig::fixed_size_configuration(1u);
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_alloc_qos_example">
        <rtps>
            <allocation>
                <!-- We know we have 3 participants on the domain -->
                <total_participants>
                    <initial>3</initial>
                    <maximum>3</maximum>
                    <increment>0</increment>
                </total_participants>
                <!-- We know we have at most 2 readers on each participant -->
                <total_readers>
                    <initial>2</initial>
                    <maximum>2</maximum>
                    <increment>0</increment>
                </total_readers>
                <!-- We know we have at most 1 writer on each participant -->
                <total_writers>
                    <initial>1</initial>
                    <maximum>1</maximum>
                    <increment>0</increment>
                </total_writers>
                <max_partitions>256</max_partitions>
                <max_user_data>256</max_user_data>
                <max_properties>512</max_properties>

                <!-- content_filter cannot be configured using XML (yet) -->
            </allocation>
        </rtps>
    </participant>

    <data_writer profile_name="allocation_qos_example_pub_for_topic_1">
        <!-- we know we will have three matching subscribers and no content filter -->
        <matchedSubscribersAllocation>
            <initial>3</initial>
            <maximum>3</maximum>
            <increment>0</increment>
        </matchedSubscribersAllocation>

        <!-- reader_filters_allocation cannot be configured using XML (yet) -->
    </data_writer>

    <data_writer profile_name="allocation_qos_example_pub_for_topic_2">
        <!-- we know we will have two matching subscribers and no content filter -->
        <matchedSubscribersAllocation>
            <initial>2</initial>
            <maximum>2</maximum>
            <increment>0</increment>
        </matchedSubscribersAllocation>

        <!-- reader_filters_allocation cannot be configured using XML (yet) -->
    </data_writer>

    <data_reader profile_name="allocation_qos_example_sub">
        <!-- we know we will only have one matching publisher -->
        <matchedPublishersAllocation>
            <initial>1</initial>
            <maximum>1</maximum>
            <increment>0</increment>
        </matchedPublishersAllocation>
    </data_reader>
</profiles>

15.6.2. Non-blocking calls

Note

As OSX does not support necessary POSIX Real-time features, this feature is not fully supported on OSX. In that case, the feature is limited by the implementation of std::timed_mutex and std::condition_variable_any.

Several functions on the Fast DDS API can be blocked for an undefined period of time when operations compete for the control of a resource. The blocked function cannot continue until the operation that gained the control finishes, thus blocking the calling thread.

Real-time applications need a predictable behavior, including a predictable maximum time since a function is called until it returns control. In order to comply with this restriction, Fast DDS can be configured to limit the maximum blocking time of these functions. If the blocking time limit is exceeded, the requested operation is aborted and function terminated, returning the control to the caller.

This configuration needs two steps:

  • Set the CMake option -DSTRICT_REALTIME=ON during the compilation of the application.

  • Configure the maximum blocking times for the functions.

Fast RTPS non-blocking API

Method

Configuration attribute

Default value

DataWriter::write()

reliability().max_blocking_time on DataWriterQos.

100 milliseconds.

DataReader::take_next_sample()

reliability().max_blocking_time on DataReaderQos.

100 milliseconds.

DataReader::read_next_sample()

reliability().max_blocking_time on DataReaderQos.

100 milliseconds.

DataReader::wait_for_unread_message()

The method accepts an argument with the maximum blocking time.

15.7. Reduce memory usage

A great number of modern systems have tight constraints on available memory, making the reduction of memory usage to a minimum critical. Reducing memory consumption of a Fast DDS application can be achieved through various approaches, mainly through architectural restructuring of the application, but also by limiting the resources the middleware utilizes, and by avoiding static allocations.

15.7.1. Limiting Resources

The ResourceLimitsQosPolicy controls the resources that the service can use in order to meet the requirements imposed. It limits the amount of allocated memory per DataWriter or DataReader, as per the following parameters:

  • max_samples: Configures the maximum number of samples that the DataWriter or DataReader can manage across all the instances associated with it, i.e. it represents the maximum samples that the middleware can store for a DataReader or DataWriter.

  • max_instances: Configures the maximum number of instances that the DataWriter or DataReader can manage.

  • max_samples_per_instance: Controls the maximum number of samples within an instance that the DataWriter or DataReader can manage.

  • allocated_samples: States the number of samples that will be allocated on initialization.

All these parameters may be lowered as much as needed to reduce memory consumption, limit the resources to the application’s needs. Below is an example of a configuration for the minimum resource limits possible.

Warning

ResourceLimitsQosPolicy resource_limits;

// The ResourceLimitsQosPolicy is constructed with max_samples = 5000 by default
// Change max_samples to the minimum
resource_limits.max_samples = 1;

// The ResourceLimitsQosPolicy is constructed with max_instances = 10 by default
// Change max_instances to the minimum
resource_limits.max_instances = 1;

// The ResourceLimitsQosPolicy is constructed with max_samples_per_instance = 400 by default
// Change max_samples_per_instance to the minimum
resource_limits.max_samples_per_instance = 1;

// The ResourceLimitsQosPolicy is constructed with allocated_samples = 100 by default
// No allocated samples
resource_limits.allocated_samples = 0;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <data_writer profile_name="data_writer_min_samples">
        <topic>
            <historyQos>
                <kind>KEEP_LAST</kind>
                <depth>1</depth>
            </historyQos>
            <resourceLimitsQos>
                <max_samples>1</max_samples>
                <max_instances>1</max_instances>
                <max_samples_per_instance>1</max_samples_per_instance>
                <allocated_samples>0</allocated_samples>
            </resourceLimitsQos>
        </topic>
    </data_writer>

    <data_reader profile_name="data_reader_min_samples">
        <topic>
            <historyQos>
                <kind>KEEP_LAST</kind>
                <depth>1</depth>
            </historyQos>
            <resourceLimitsQos>
                <max_samples>1</max_samples>
                <max_instances>1</max_instances>
                <max_samples_per_instance>1</max_samples_per_instance>
                <allocated_samples>0</allocated_samples>
            </resourceLimitsQos>
        </topic>
    </data_reader>
</profiles>

15.7.2. Set Dynamic Allocation

By default MemoryManagementPolicy is set to PREALLOCATED_WITH_REALLOC_MEMORY_MODE, meaning that the amount of memory required by the configured ResourceLimitsQosPolicy will be allocated at initialization. If some more memory has to be allocated at run time, it is reallocated.

Using the dynamic settings of the RTPSEndpointQos will prevent unnecessary allocations. Lowest footprint is achieved with DYNAMIC_RESERVE_MEMORY_MODE at the cost of higher allocation counts, in this mode memory is allocated when needed and freed as soon as it stops being used. For higher determinism at a small memory cost the DYNAMIC_REUSABLE_MEMORY_MODE option is available, this option is similar but once more memory is allocated it is not freed and is reused for future messages.

RTPSEndpointQos endpoint;
endpoint.history_memory_policy = eprosima::fastdds::rtps::DYNAMIC_REUSABLE_MEMORY_MODE;
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <data_writer profile_name="data_writer_low_memory">
        <!-- ...  -->
        <historyMemoryPolicy>DYNAMIC_REUSABLE</historyMemoryPolicy>
    </data_writer>

    <data_reader profile_name="data_reader_low_memory">
        <!-- ...  -->
        <historyMemoryPolicy>DYNAMIC_REUSABLE</historyMemoryPolicy>
    </data_reader>
</profiles>

15.8. Zero-Copy communication

This section explains how to configure a Zero-Copy communication in Fast DDS. The Zero-Copy communication allows the transmission of data between applications without copying data in memory, saving time and resources. In order to achieve this, it uses Data-sharing delivery between the DataWriter and the DataReader, and data buffer loans between the application and Fast DDS.

15.8.1. Overview

Data-sharing delivery provides a communication channel between a DataWriter and a DataReader using shared memory. Therefore, it does not require copying the sample data to transmit it.

DataWriter sample loaning is a Fast DDS extension that allows the application to borrow a buffer for a sample in the publishing DataWriter. The sample can be constructed directly on this buffer, eliminating the need to copy it to the DataWriter afterwards. This prevents the copying of the data between the publishing application and the DataWriter. If Data-sharing delivery is used, the loaned data buffer will be in the shared memory itself.

Reading the data on the subscriber side can also be done with loans from the DataReader. The application gets the received samples as a reference to the receive queue itself. This prevents the copying of the data from the DataReader to the receiving application. Again, if Data-sharing delivery is used, the loaned data will be in the shared memory, and will indeed be the same memory buffer used in the DataWriter history.

Combining these three features, we can achieve Zero-Copy communication between the publishing application and the subscribing application.

15.8.2. Getting started

To enable Zero-Copy perform the following steps:

  1. Define a plain and bounded type in an IDL file and generate the corresponding source code for further processing with the Fast DDS-Gen tool.

    @extensibility(FINAL)
    struct LoanableHelloWorld
    {
        unsigned long index;
        char message[256];
    };
    
  2. On the DataWriter side:

    1. Create a DataWriter for the previous type. Make sure that the DataWriter does not have DataSharing disabled.

    2. Get a loan on a sample using loan_sample().

    3. Write the sample using write().

  3. On the DataReader side:

    1. Create a DataReader for the previous type. Make sure that the DataReader does not have DataSharing disabled.

    2. Take/read samples using the available functions in the DataReader. Please refer to section Loaning and Returning Data and SampleInfo Sequences for further detail on how to access to loans of the received data.

    3. Return the loaned samples using DataReader::return_loan().

15.8.3. Writing and reading in Zero-Copy transfers

The following is an example of how to publish and receive samples with DataWriters and DataReaders respectively that implement Zero-Copy.

15.8.3.1. DataWriter

When the DataWriter is created, Fast DDS will pre-allocate a pool of max_samples + extra_samples samples that reside in a shared memory mapped file. This pool will be used to loan samples when the loan_sample() function is called.

An application example of a DataWriter that supports Zero-Copy using the Fast DDS library is presented below. There are several points to note in the following code:

  • Not disabling the DataSharingQosPolicy. AUTO kind automatically enables Zero-Copy when possible.

  • The use of the loan_sample() function to access and modify data samples.

  • The writing of data samples.

// CREATE THE PARTICIPANT
DomainParticipantQos pqos;
pqos.name("Participant_pub");
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, pqos);

// REGISTER THE TYPE
TypeSupport type(new LoanableHelloWorldPubSubType());
type.register_type(participant);

// CREATE THE PUBLISHER
Publisher* publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT, nullptr);

// CREATE THE TOPIC
Topic* topic = participant->create_topic(
    "LoanableHelloWorldTopic",
    type.get_type_name(),
    TOPIC_QOS_DEFAULT);

// CREATE THE WRITER
DataWriterQos wqos = publisher->get_default_datawriter_qos();
wqos.history().depth = 10;
wqos.durability().kind = TRANSIENT_LOCAL_DURABILITY_QOS;
// DataSharingQosPolicy has to be set to AUTO (the default) or ON to enable Zero-Copy
wqos.data_sharing().on("shared_directory");

DataWriter* writer = publisher->create_datawriter(topic, wqos);

std::cout << "LoanableHelloWorld DataWriter created." << std::endl;

int msgsent = 0;
void* sample = nullptr;
// Always call loan_sample() before writing a new sample.
// This function will provide the user with a pointer to an internal buffer where the data type can be
// prepared for sending.
if (RETCODE_OK == writer->loan_sample(sample))
{
    // Modify the sample data
    LoanableHelloWorld* data = static_cast<LoanableHelloWorld*>(sample);
    data->index() = msgsent + 1;
    memcpy(data->message().data(), "LoanableHelloWorld ", 20);

    std::cout << "Sending sample (count=" << msgsent
              << ") at address " << &data << std::endl
              << "  index=" << data->index() << std::endl
              << "  message=" << data->message().data() << std::endl;

    // Write the sample.
    // After this function returns, the middleware owns the sample.
    writer->write(sample);
}
15.8.3.2. DataReader

The following is an application example of a DataReader that supports Zero-Copy using the Fast DDS library. As shown in this code snippet, the configuration in the DataReader is similar to the DataWriter. Be sure not to disable the DataSharingQosPolicy. AUTO kind automatically enables Zero-Copy when possible.

// CREATE THE PARTICIPANT
DomainParticipantQos pqos;
pqos.name("Participant_sub");
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, pqos);

// REGISTER THE TYPE
TypeSupport type(new LoanableHelloWorldPubSubType());
type.register_type(participant);

// CREATE THE SUBSCRIBER
Subscriber* subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr);

// CREATE THE TOPIC
Topic* topic = participant->create_topic(
    "LoanableHelloWorldTopic",
    type.get_type_name(),
    TOPIC_QOS_DEFAULT);

// CREATE THE READER
DataReaderQos rqos = subscriber->get_default_datareader_qos();
rqos.history().depth = 10;
rqos.reliability().kind = RELIABLE_RELIABILITY_QOS;
rqos.durability().kind = TRANSIENT_LOCAL_DURABILITY_QOS;
// DataSharingQosPolicy has to be set to AUTO (the default) or ON to enable Zero-Copy
rqos.data_sharing().automatic();

DataReader* reader = subscriber->create_datareader(topic, rqos, &datareader_listener);

Finally, the code snippet below implements the on_data_available() DataReaderListener callback. The key points to be noted in this function are:

void on_data_available(
        eprosima::fastdds::dds::DataReader* reader) override
{
    // Declare a LoanableSequence for a data type
    FASTDDS_SEQUENCE(DataSeq, LoanableHelloWorld);

    DataSeq data;
    SampleInfoSeq infos;
    // Access to the collection of data-samples and its corresponding collection of SampleInfo structures
    while (RETCODE_OK == reader->take(data, infos))
    {
        // Iterate over each LoanableCollection in the SampleInfo sequence
        for (LoanableCollection::size_type i = 0; i < infos.length(); ++i)
        {
            // Check whether the DataSample contains data or is only used to communicate of a
            // change in the instance
            if (infos[i].valid_data)
            {
                // Print the data.
                const LoanableHelloWorld& sample = data[i];

                ++samples;
                std::cout << "Sample received (count=" << samples
                          << ") at address " << &sample
                          << (reader->is_sample_valid(&sample,
                &infos[i]) ? " is valid" : " was replaced" ) << std::endl
                          << "  index=" << sample.index() << std::endl
                          << "  message=" << sample.message().data() << std::endl;
            }
        }
        // Indicate to the DataReader that the application is done accessing the collection of
        // data values and SampleInfo, obtained by some earlier invocation of read or take on the
        // DataReader.
        reader->return_loan(data, infos);
    }
}

15.8.4. Caveats

  • After calling write(), Fast DDS takes ownership of the sample and therefore it is no longer safe to make changes to that sample.

  • If function loan_sample() is called first and the sample is never written, it is necessary to use function discard_loan() to return the sample to the DataWriter. If this is not done, the subsequent calls to loan_sample() may fail if DataWriter has no more extra_samples to loan.

  • The current maximum supported sample size is the maximum value of an uint32_t.

15.8.5. Constraints

Although Zero-Copy can be used for one or several Fast DDS application processes running on the same machine, it has some constraints:

  • Only plain types are supported.

    A plain type is a type whose CDR representation matches its in-memory representation. This requirement avoids the copy between the CDR buffer and the user buffer because the data representation is the same. Consequently, only primitive types (except string), arrays of these primitive types, and structures with FINAL extensibility and members of these primitive types, are considered to be plain (Fast DDS also provides an API to check if a defined type is plain: TypeSupport::is_plain()).

  • Constraints for datasharing delivery also apply.

Note

Zero-Copy transfer support for non-plain types may be implemented in future releases of Fast DDS.

15.8.6. Next steps

A hello world example suitable for supported delivery mechanisms can be found in the delivery_mechanisms folder. It shows a publisher and a subscriber that communicate through the desired delivery mechanism. As long as it is zero-copy compatible, both intra-process and data-sharing delivery mechanisms are zero-copy if used.

15.9. Unique network flows

This section explains which APIs should be used on Fast DDS in order to have unique network flows on specific topics.

15.9.1. Background

IP networking is the pre-dominant inter-networking technology used nowadays. Ethernet, WiFi, 4G/5G telecommunication, all of them rely on IP networking.

Streams of IP packets from a given source to destination are called packet flows or simply flows. The network QoS of a flow can be configured when using certain networking equipment (routers, switches). Such pieces of equipment typically support 3GPP/5QI protocols to assign certain Network QoS parameters to specific flows. Requesting a specific Network QoS is usually done on the endpoint sending the data, as it is the one that usually haves complete information about the network flow.

Applications may need to use specific Network QoS parameters on different topics.

This means an application should be able to:

  1. Identify the flows being used in the communications, so they can correctly configure the networking equipment.

  2. Use specific flows on selected topics.

15.9.2. Identifying a flow

The 5-tuple is a traditional unique identifier for flows on 3GPP enabled equipment. The 5-tuple consists of five parameters: source IP address, source port, destination IP address, destination port, and the transport protocol (example, TCP/UDP).

15.9.2.1. Definitions

Network flow: A tuple of networking resources selected by the middleware for transmission of messages from a DataWriter to a DataReader, namely:

  • Transport protocol: UDP or TCP

  • Transport port

  • Internet protocol: IPv4 or IPv6

  • IP address

Network Flow Endpoint (NFE): The portion of a network flow specific to the DataWriter or the DataReader. In other words, each network flow has two NFEs; one for the DataWriter, and the other for the DataReader.

15.9.2.2. APIs

Fast DDS provides the APIs needed to get the list of NFEs used by a given DataWriter or a DataReader.

  • On the DataWriter, get_sending_locators() allows the application to obtain the list of locators from which the writer may send data.

  • On the DataReader, get_listening_locators() allows the application to obtain the list of locators on which the reader is listening.

15.9.3. Requesting unique flows

A unique flow can be created by ensuring that at least one of the two NFEs are unique. On Fast DDS, there are two ways to select unique listening locators on the DataReader:

  • The application can specify on which locators the DataReader should be listening. This is done using RTPSEndpointQos on the DataReaderQos. In this case it is the responsibility of the application to ensure the uniqueness of the locators used.

  • The application can request the reader to be created with unique listening locators. This is done using a PropertyPolicyQos including the property "fastdds.unique_network_flows". In this case, the reader will listen on a unique port outside the range of ports typically used by RTPS.

15.9.4. Example

The following snippet demonstrates all the APIs described on this page:

// Create the DataWriter
DataWriter* writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == writer)
{
    // Error
    return;
}

// Create DataReader with unique flows
DataReaderQos drqos = DATAREADER_QOS_DEFAULT;
drqos.properties().properties().emplace_back("fastdds.unique_network_flows", "");
DataReader* reader = subscriber->create_datareader(topic, drqos);

// Print locators information
eprosima::fastdds::rtps::LocatorList locators;
writer->get_sending_locators(locators);
std::cout << "Writer is sending from the following locators:" << std::endl;
for (const auto& locator : locators)
{
    std::cout << "  " << locator << std::endl;
}

reader->get_listening_locators(locators);
std::cout << "Reader is listening on the following locators:" << std::endl;
for (const Locator_t& locator : locators)
{
    std::cout << "  " << locator << std::endl;
}

15.10. Statistics module

eProsima Fast DDS Statistics Module allows the user to monitor the data being exchanged by its application. In order to use this module, the user must enable it in the monitored application, and create another application that receives the data being published by the statistics DataWriters. The user can also use for the latter the eProsima Fast DDS Statistics Backend which already implements the collection and aggregation of the data coming from the statistics topics.

15.10.1. Enable Statistics module

The Statistics module has to be enabled both at build and runtime. On the one hand, CMake option FASTDDS_STATISTICS must be enabled when building the library (since Fast DDS v2.9.0 this CMake option is enabled by default). On the other hand, the desired statistics DataWriters should be enabled using the Statistics Module DDS Layer.

The statistics DataWriters can be enabled automatically using the PropertyPolicyQos fastdds.statistics and the FASTDDS_STATISTICS environment variable. They can also be enabled manually following the next example:

// Create a DomainParticipant
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Obtain pointer to child class
eprosima::fastdds::statistics::dds::DomainParticipant* statistics_participant =
        eprosima::fastdds::statistics::dds::DomainParticipant::narrow(participant);

// Enable statistics DataWriter
if (statistics_participant->enable_statistics_datawriter(eprosima::fastdds::statistics::GAP_COUNT_TOPIC,
        eprosima::fastdds::statistics::dds::STATISTICS_DATAWRITER_QOS) != RETCODE_OK)
{
    // Error
    return;
}

// Use the DomainParticipant to communicate
// (...)

// Disable statistics DataWriter
if (statistics_participant->disable_statistics_datawriter(eprosima::fastdds::statistics::GAP_COUNT_TOPIC) !=
        RETCODE_OK)
{
    // Error
    return;
}

// Delete DomainParticipant
if (DomainParticipantFactory::get_instance()->delete_participant(participant) != RETCODE_OK)
{
    // Error
    return;
}

15.10.2. Create monitoring application

Once the monitored application is publishing the collected data within the statistics topics enabled by the user, another application should be configured to subscribe to those topics. This application is a DDS standard application where the statistics DataReaders should be created. In order to create these statistics DataReaders, the user should follow the next steps:

15.11. Dynamic network interfaces

DDS Simple Discovery relies on well-known multicast addresses and ports to relay the Participant announcement messages (see Discovery phases). Such Participant announcement includes information about the unicast address-port pairs (a.k.a locators) where the Participant is expecting to receive incoming metatraffic data. The list with these unicast locators is automatically initialized taking into account the network interfaces that are available when the Fast DDS DomainParticipant is enabled. Consequently, any network interface that is added after enabling the DomainParticipant should be notified to Fast DDS in order to initialize an unicast locator in said network, so communication can be established over that new interface.

15.11.1. Dynamic network interface addition at run-time

In case that the user wants to include new network interfaces at run-time, some prerequisites have to be fulfilled. Then, once the interfaces are available, the user may notify Fast DDS so these interfaces are also used in the communication.

15.11.1.1. Prerequisites

This feature is intended to be used when Fast DDS automatically sets the listening unicast locators. Consequently, both metatrafficUnicastLocatorList and metatrafficMulticastLocatorList lists must be empty. These attributes are set within the builtin member of wire_protocol() contained in the DomainParticipantQos (please refer to DomainParticipantQos).

Note

Be aware of the remote locators’ collections limits set within the DomainParticipantQos (please refer to RemoteLocatorsAllocationAttributes). It is recommended to use the highest number of local addresses found on all the systems belonging to the same domain.

15.11.1.2. Notify Fast DDS

Once a new network interface has been enabled, Fast DDS has to be manually notified. This is done calling DomainParticipant::set_qos(). The DomainParticipantQoS that is passed to the method can either change one of the mutable DomainParticipant QoS or it can simply be the current DomainParticipant QoS (obtained with DomainParticipant::get_qos()).

Using DomainParticipant::set_qos() is the reason for the previous prerequisites: once the DomainParticipant is enabled, there are several QoS policies that are immutable and cannot be changed at run-time. WireProtocolConfigQos where the aforementioned lists are defined is among these immutable policies.

Find below a brief snippet of how to use this feature:

// Create the DomainParticipant
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// User application

// Notify Fast DDS a new network interface is available
participant->set_qos(PARTICIPANT_QOS_DEFAULT);

Important

This feature is still under development and only officially supported for UDPv4 Transport without whitelisting.

15.12. How to use eProsima DDS Record and Replay

eProsima DDS Record and Replay is an end-user software application that efficiently saves DDS data published into a DDS environment in a MCAP format database. Thus, the exact playback of the recorded network events is possible as the data is linked to the timestamp at which the original data was published. This facilitates the debugging of DDS networks.

15.12.1. Getting started

eProsima DDS Record & Replay includes the following tools:

  • DDS Recorder tool: This tool’s primary function is to store data in an MCAP database, including the publication timestamp, serialized data, and its format. The output MCAP file can be read by any compatible tool, as it contains all necessary information for data reproduction.

  • DDS Remote Controller tool: This application enables remote control of the recording tool, allowing a user to start, stop, or pause data recording from another device.

  • DDS Replay tool: This application allows replay of DDS traffic recorded with a DDS Recorder. Users can select messages to replay by setting a time range or by blocking/whitelisting specific topics. They can also adjust the playback rate and use different topic QoS settings from the original recording.

15.12.1.1. Prerequisites

eProsima DDS Record and Replay depends on eProsima Fast DDS library and certain Debian packages. For further information, please refer to the installation guide.

Furthermore, the example provided in this section requires ShapesDemo to publish and subscribe shapes of different colors and sizes.

15.12.2. Example of usage: Recording Application

This example will serve as a hands-on tutorial, aimed at introducing some of the key concepts and features that eProsima DDS Record & Replay recording application offers.

15.12.2.1. Start ShapesDemo

Let us launch a ShapesDemo instance and start publishing in topics Square with default settings.

_images/recorder_shapesdemo_publisher.png
15.12.2.2. Recorder configuration

ddsrecorder runs with default configuration settings. This default configuration records all messages of all DDS Topics found in DDS Domain 0 in the output_YYYY-MM-DD-DD_hh-mm-ss.mcap file.

Additionally, it is possible to change the default configuration parameters by means of a YAML configuration file.

Note

Please refer to Configuration for more information on how to configure a ddsrecorder.

15.12.2.3. Recorder execution

To start recording, execute the following command:

ddsrecorder

In order to know all the possible arguments supported by this tool, use the command:

ddsrecorder --help

Let us launch a ShapesDemo instance and start publishing in topics Square with default settings.

_images/recorder_shapesdemo_exec.png

Stop the recorder with Ctrl+C and check that the MCAP file exists.

15.13. Next Steps

Once having finished a recording session, it is possible to play it back by using DDS Replay tool, as shown in this tutorial.

For further information, please refer to the eProsima DDS Record and Replay documentation.

15.14. Request-Reply communication

This section explains how to configure a Request-Reply communication in Fast DDS between two applications. A Client application will send a Request to the Server application and this one, after processing the request, will send a Reply to the Client application.

 node "Client application" as client {
 }

 node "Server application" as server {
 }

 client --> server : Request
 server --> client : Reply

15.14.1. Overview

This kind of communication involves in the DDS paradigm the usage of two Topics: one for sending requests (Request Topic) and the other one for sending replies (Reply Topic). For managing these Topics four DDS entities are involved: a DataReader and a DataWriter for each Topic. The DDS communication schema will be:

 node "Server application" {
     cloud "Processing" as Processing
     [Request DataReader] -right-> Processing
     Processing -right-> [Reply DataWriter]
 }

 node "Client application" {
     [Reply DataReader]
     [Request DataWriter]
 }

 [Request DataWriter] -down-> [Request DataReader] : Request Topic
 [Reply DataWriter] --> [Reply DataReader] : Reply Topic

The key for making Request-Reply work is relating the Request with the Reply in the client’s side. Fast DDS API provides SampleIdentity to achieve this.

A full example can be found in Fast DDS repository.

15.14.2. Getting started

For Request-Reply communication perform the following steps:

  1. Define two structures in an IDL file. One structure will be used as Request Topic’s data type and the other one as Reply Topic’s data type.

    enum OperationType
    {
        ADDITION,
        SUBSTRACTION,
        MULTIPLICATION,
        DIVISION
    };
    
    struct RequestType
    {
        OperationType operation;
        long x;
        long y;
    };
    
    struct ReplyType
    {
        long long z;
    };
    
  2. In the client application, create a DataWriter for the request and a DataReader for the reply.

    participant->register_type(request_type);
    participant->register_type(reply_type);
    
    Topic* request_topic = participant->create_topic("CalculatorRequest",
                    request_type.get_type_name(), TOPIC_QOS_DEFAULT);
    
    Topic* reply_topic =
            participant->create_topic("CalculatorReply", reply_type.get_type_name(), TOPIC_QOS_DEFAULT);
    
    DataWriter* request_writer = publisher->create_datawriter(request_topic, DATAWRITER_QOS_DEFAULT);
    
    DataReader* reply_reader = subscriber->create_datareader(reply_topic, DATAREADER_QOS_DEFAULT, &listener);
    
  3. In the server application, create a DataWriter for the reply and a DataReader for the request.

    participant->register_type(request_type);
    participant->register_type(reply_type);
    
    Topic* request_topic = participant->create_topic("CalculatorRequest",
                    request_type.get_type_name(), TOPIC_QOS_DEFAULT);
    
    Topic* reply_topic =
            participant->create_topic("CalculatorReply", reply_type.get_type_name(), TOPIC_QOS_DEFAULT);
    
    DataWriter* reply_writer = publisher->create_datawriter(reply_topic, DATAWRITER_QOS_DEFAULT);
    
    DataReader* request_reader = subscriber->create_datareader(request_topic, DATAREADER_QOS_DEFAULT, &listener);
    

15.14.3. Sending the request and storing the assigned identifier

For sending the request, the client application should retrieve and store the internal identifier assigned to the published sample. Therefore the sample should be published using the overloaded write() function which second argument is a reference to a WriteParams object. The assigned identifier will be stored in the WriteParams’s attribute sample_identity().

eprosima::fastdds::rtps::SampleIdentity my_request_sample_identity;
RequestType request;

// Fill the request

// Publish request
eprosima::fastdds::rtps::WriteParams write_params;
request_writer->write(static_cast<void*>(&request), write_params);

// Store sample identity
my_request_sample_identity = write_params.sample_identity();

15.14.4. Receiving the request and sending a reply associated with it

When the server application receives the request (for example through on_data_available()), it has to retrieve the request’s identifier using sample_identity.

void on_data_available(
        eprosima::fastdds::dds::DataReader* reader) override
{
    RequestType request;
    eprosima::fastdds::dds::SampleInfo sample_info;

    reader->take_next_sample(&request, &sample_info);

    if (eprosima::fastdds::dds::InstanceStateKind::ALIVE_INSTANCE_STATE == sample_info.instance_state)
    {
        // Store the request identity.
        eprosima::fastdds::rtps::SampleIdentity client_request_identity = sample_info.sample_identity;
    }
}

After processing the request, the server should send the reply to the client with the related request attached. This is done assigning the stored identifier in related_sample_identity().

ReplyType reply;

// Fill reply

// Send reply associating it with the client request.
eprosima::fastdds::rtps::WriteParams write_params;
write_params.related_sample_identity() = client_request_identity;
reply_writer->write(reinterpret_cast<void*>(&reply), write_params);

15.14.5. Identifying the reply for the client

When the client application receives a reply (for example through on_data_available()), the client application should identify if the received reply is the one expected for its request. For this the client application has to compare the stored SampleIdentity with the incoming related_sample_identity.

void on_data_available(
        eprosima::fastdds::dds::DataReader* reader) override
{
    ReplyType reply;
    eprosima::fastdds::dds::SampleInfo sample_info;

    reader->take_next_sample(&reply, &sample_info);

    if (eprosima::fastdds::dds::InstanceStateKind::ALIVE_INSTANCE_STATE == sample_info.instance_state)
    {
        if (sample_info.related_sample_identity == my_request_sample_identity)
        {
            // Work to do
        }
    }
}

15.15. Remote type discovery and endpoint matching

This section explains how to create an endpoint using a remotely discovered data type that was previously unknown to the local participant.

15.15.1. Prerequisites

This use case focuses on the strategy to follow in order to create an endpoint at runtime in a previously unknown topic using the information provided by the remote endpoint discovery information. Therefore, the prerequisites are:

  • Two participants, A and B, running in different process (type information is shared within the same DomainParticipantFactory).

  • Participant A must not know the data type registered in participant B.

  • Participant B data type must be registered using the code generated by eProsima Fast DDS-Gen without disabling the TypeObjectSupport code generation.

  • Participant B must create an endpoint using the data type unknown by participant A.

  • Participant A must be attached to a DomainParticipantListener.

15.15.2. Remote type discovery

Following the participant discovery phase, the endpoint information is exchanged. The appropriate on_data_reader_discovery() or on_data_writer_discovery() callback is called, depending on the kind of endpoint created on the remote participant. The endpoint discovery callback provides access to the remotely discovered information including the TypeInformation.

Provided the TypeInformation, ITypeObjectRegistry singleton can be queried for the corresponding TypeObject representation calling ITypeObjectRegistry::get_type_object API.

15.15.3. Register remote type

DynamicTypeBuilderFactory provides a specific API that given a TypeObject representation returns the corresponding DynamicTypeBuilder: DynamicTypeBuilderFactory::create_type_w_type_object. The DynamicType can then be obtained and registered using DynamicPubSubType.

15.15.4. Create local endpoint

Once the remote type has been locally registered, a Topic can be created within the DomainParticipant and endpoints using this Topic might be also created.

Note

Endpoint matching takes into consideration QoS consistency. Consequently, for the local endpoint to match, the remote QoS has to be taken into account. The remote endpoint discovery information provided by the discovery callback includes also this data.

15.15.5. Example

The following snippet shows the previously explained steps:

class RemoteDiscoveryDomainParticipantListener : public DomainParticipantListener
{
    /* Custom Callback on_data_reader_discovery */
    void on_data_reader_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::ReaderDiscoveryStatus reason,
            const eprosima::fastdds::rtps::SubscriptionBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        // Get remote type information
        xtypes::TypeObject remote_type_object;
        if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
                    info.type_information.type_information.complete().typeid_with_size().type_id(),
                    remote_type_object))
        {
            // Error
            return;
        }
        // Register remotely discovered type
        DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
            remote_type_object)->build();
        TypeSupport dyn_type_support(new DynamicPubSubType(remote_type));
        dyn_type_support.register_type(participant);

        // Create a Topic with the remotely discovered type.
        Topic* topic =
                participant->create_topic(info.topic_name.to_string(), dyn_type_support.get_type_name(),
                        TOPIC_QOS_DEFAULT);
        if (nullptr == topic)
        {
            // Error
            return;
        }

        // Create endpoint
        Publisher* publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
        if (nullptr == publisher)
        {
            // Error
            return;
        }

        DataWriter* data_writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
        if (nullptr == data_writer)
        {
            // Error
            return;
        }
    }

    /* Custom Callback on_data_writer_discovery */
    void on_data_writer_discovery(
            DomainParticipant* participant,
            eprosima::fastdds::rtps::WriterDiscoveryStatus reason,
            const eprosima::fastdds::dds::PublicationBuiltinTopicData& info,
            bool& should_be_ignored) override
    {
        should_be_ignored = false;
        // Get remote type information
        xtypes::TypeObject remote_type_object;
        if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
                    info.type_information.type_information.complete().typeid_with_size().type_id(),
                    remote_type_object))
        {
            // Error
            return;
        }
        // Register remotely discovered type
        DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
            remote_type_object)->build();
        TypeSupport dyn_type_support(new DynamicPubSubType(remote_type));
        dyn_type_support.register_type(participant);

        // Create a Topic with the remotely discovered type.
        Topic* topic =
                participant->create_topic(info.topic_name.to_string(), dyn_type_support.get_type_name(),
                        TOPIC_QOS_DEFAULT);
        if (nullptr == topic)
        {
            // Error
            return;
        }

        // Create endpoint
        Subscriber* subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
        if (nullptr == subscriber)
        {
            // Error
            return;
        }

        // The QoS depends on the remote endpoint QoS. For simplicity, default QoS have been assumed.
        DataReader* data_reader = subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
        if (nullptr == data_reader)
        {
            // Error
            return;
        }
    }

};

16. ROS 2 using Fast DDS middleware

Fast DDS is the default middleware implementation in the Open Source Robotic Fundation (OSRF) Robot Operating System ROS 2 in every long term (LTS) releases and most of the non-LTS releases.

ROS 2 is a state-of-the-art software for robot engineering which consists of a set of free software libraries and tools for building robot applications. This section presents some use cases and shows how to take full advantage of Fast DDS wide set of capabilities in a ROS 2 project.

The interface between the ROS 2 stack and Fast DDS is provided by a ROS 2 package rmw_fastrtps. This package is available in all ROS 2 distributions, both from binaries and from sources. rmw_fastrtps actually provides not one but two different ROS 2 middleware implementations, both of them using Fast DDS as middleware layer: rmw_fastrtps_cpp and rmw_fastrtps_dynamic_cpp. The main difference between the two is that rmw_fastrtps_dynamic_cpp uses introspection type support at run time to decide on the serialization/deserialization mechanism, while rmw_fastrtps_cpp uses its own type support, which generates the mapping for each message type at build time. The default ROS 2 RMW implementation in all distributions except EOL Galactic is rmw_fastrtps_cpp. For EOL Galactic the environment variable RMW_IMPLEMENTATION has to be set to select rmw_fastrtps_cpp in order to use Fast DDS as the middleware layer. This environment variable can also be used to select the rmw_fastrtps_dynamic_cpp implementation:

  1. Exporting RMW_IMPLEMENTATION environment variable:

    export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
    

    or

    export RMW_IMPLEMENTATION=rmw_fastrtps_dynamic_cpp
    
  2. When launching your ROS 2 application:

    RMW_IMPLEMENTATION=rmw_fastrtps_cpp ros2 run <package> <application>
    

    or

    RMW_IMPLEMENTATION=rmw_fastrtps_dynamic_cpp ros2 run <package> <application>
    

Note

On EOL Galactic you may have to install the rmw_fastrtps_cpp package:

sudo apt install ros-galactic-rmw-fastrtps-cpp

16.1. Configuring Fast DDS in ROS 2

ROS 2 only allows for the configuration of certain middleware QoS (see ROS 2 QoS policies). However, rmw_fastrtps offers extended configuration capabilities to take full advantage of the features in Fast DDS. This section describes how to specify this extended configuration.

16.1.1. Changing publication mode

rmw_fastrtps in ROS 2 uses synchronous publication by default. This can be easily changed setting the environment variable RMW_FASTRTPS_PUBLICATION_MODE to one of the following allowed values:

  • ASYNCHRONOUS: asynchronous publication mode. Setting this mode implies that when the publisher invokes the write operation, the data is copied into a queue, a background thread (asynchronous thread) is notified about the addition to the queue, and control of the thread is returned to the user before the data is actually sent. The background thread is in charge of consuming the queue and sending the data to every matched reader.

  • SYNCHRONOUS: synchronous publication mode. Setting this mode implies that the data is sent directly within the context of the user thread. This entails that any blocking call occurring during the write operation would block the user thread, thus preventing the application from continuing its operation. It is important to note that this mode typically yields higher throughput rates at lower latencies, since there is no notification nor context switching between threads.

  • AUTO: let Fast DDS select the publication mode. This implies using the publication mode set in the XML file, or otherwise, the default value set in Fast DDS (see PublishModeQosPolicy).

rmw_fastrtps defines two configurable parameters in addition to ROS 2 QoS policies. Said parameters, and their default values under ROS 2, are:

Parameter

Description

Default ROS 2 value

MemoryManagementPolicy

Fast DDS preallocates memory for the publisher
and subscriber histories. When those histories fill
up, a reallocation occurs to reserve more memory.

PREALLOCATED_WITH_REALLOC_MEMORY_MODE

PublishModeQosPolicy

User calls to publication method add the messages
in a queue that is managed in a different thread,
meaning that the user thread is available right
after the call to send data.

SYNCHRONOUS_PUBLISH_MODE

16.1.2. XML configuration

To use specific Fast-DDS features within a ROS 2 application, XML configuration files can be used to configure a wide set of QoS. Please refer to XML profiles to see the whole list of configuration options available in Fast DDS.

When configuring rmw_fastrtps using XML files, there are certain points that have to be taken into account:

  • ROS 2 QoS contained in rmw_qos_profile_t are always honored, unless set to *_SYSTEM_DEFAULT. In that case, XML values, or Fast DDS default values in the absences of XML ones, are applied. This means that if any QoS in rmw_qos_profile_t is set to something other than *_SYSTEM_DEFAULT, the corresponding value in the XML is ignored.

  • By default, rmw_fastrtps overrides the values for MemoryManagementPolicy and PublishModeQosPolicy. This means that the values configured in the XML for these two parameters will be ignored. Instead, PREALLOCATED_WITH_REALLOC_MEMORY_MODE and ASYNCHRONOUS_PUBLISH_MODE are used respectively.

  • The override of MemoryManagementPolicy and PublishModeQosPolicy can be avoided by setting the environment variable RMW_FASTRTPS_USE_QOS_FROM_XML to 1 (its default value is 0). This will make rmw_fastrtps use the values defined in the XML for MemoryManagementPolicy and PublishModeQosPolicy. Bear in mind that setting this environment variable but not setting these policies in the XML results in using the default values in Fast DDS. These are different from the aforementioned rmw_fastrtps default values (see MemoryManagementPolicy and PublishModeQosPolicy).

  • Setting RMW_FASTRTPS_USE_QOS_FROM_XML effectively overrides whatever configuration was set with RMW_FASTRTPS_PUBLICATION_MODE, setting the publication mode to the value specified in the XML, or to the Fast DDS default publication mode if none is set in the XML.

The following table summarizes which values are used or ignored according to the configured variables:

RMW_FASTRTPS_USE_QOS_FROM_XML

rmw_qos_profile_t

Fast DDS XML QoS

Fast DDS XML history memory policy
and publication mode

0 (default)

Default values

Overridden by
rmw_qos_profile_t

Overridden by
rmw_fastrtps default value

0 (default)

Non system default

overridden by
rmw_qos_profile_t

Overridden by
rmw_fastrtps default value

0 (default)

System default

Used

Overridden by
rmw_fastrtps default value

1

Default values

Overridden by
rmw_qos_profile_t

Used

1

Non system default

Overridden by
rmw_qos_profile_t

Used

1

System default

Used

Used

16.1.2.1. XML configuration file location

There are two possibilities for providing Fast DDS with XML configuration files:

  • Recommended: Setting the location with environment variable FASTDDS_DEFAULT_PROFILES_FILE to contain the path to the XML configuration file (see Environment variables).

    export FASTDDS_DEFAULT_PROFILES_FILE=<path_to_xml_file>
    
  • Alternative: Placing the XML file in the running application directory under the name DEFAULT_FASTDDS_PROFILES.xml.

For example:

export FASTDDS_DEFAULT_PROFILES_FILE=<path_to_xml_file>
export RMW_FASTRTPS_USE_QOS_FROM_XML=1
ros2 run <package> <application>
16.1.2.2. Applying different profiles to different entities

rmw_fastrtps allows for the configuration of different entities with different QoS using the same XML file. For doing so, rmw_fastrtps locates profiles in the XML based on topic names.

16.1.2.2.1. Creating publishers/subscribers with different profiles
  • To configure a publisher, define a <data_writer> profile with attribute profile_name=topic_name, where topic_name is the name of the topic prepended by the node namespace (which defaults to “” if not specified), i.e. the node’s namespace followed by topic name used to create the publisher. Mind that topic names always start with / (it is added when creating the topic if not present), and that namespace and topic name are always separated by one /. If such profile is not defined, rmw_fastrtps attempts to load the <data_writer> profile with attribute is_default_profile="true".

  • To configure a subscriber, define a <data_reader> profile with attribute profile_name=topic_name, where topic_name is the name of the topic prepended by the node namespace (which defaults to “” if not specified), i.e. the node’s namespace followed by topic name used to create the subscriber. Mind that topic names always start with / (it is added when creating the topic if not present), and that namespace and topic name are always separated by one /. If such profile is not defined, rmw_fastrtps attempts to load the <data_reader> profile with attribute is_default_profile="true".

The following table presents different combinations of node namespaces and user specified topic names, as well as the resulting topic names and the suitable profile names:

User specified topic name

Node namespace

Final topic name

Profile name

chatter

DEFAULT (“”)

/chatter

/chatter

chatter

test_namespace

/test_namespace/chatter

/test_namespace/chatter

chatter

/test_namespace

/test_namespace/chatter

/test_namespace/chatter

/chatter

test_namespace

/chatter

/chatter

/chatter

/test_namespace

/chatter

/chatter

Important

Node namespaces are NOT prepended to user specified topic names starting with /, a.k.a Fully Qualified Names (FQN). For a complete description of topic name remapping please refer to Remapping Names.

16.1.2.2.2. Creating services with different profiles

ROS 2 services contain a subscriber for receiving requests, and a publisher to reply to them. rmw_fastrtps allows for configuring each of these endpoints separately in the following manner:

  • To configure the request subscriber, define a <data_reader> profile with attribute profile_name=topic_name, where topic_name is the name of the service after mangling. For more information on name mangling, please refer to Topic and Service name mapping to DDS. If such profile is not defined, rmw_fastrtps attempts to load a <data_reader> profile with attribute profile_name="service". If neither of the previous profiles exist, rmw_fastrtps attempts to load the <data_reader> profile with attribute is_default_profile="true".

  • To configure the reply publisher, define a <data_writer> profile with attribute profile_name=topic_name, where topic_name is the name of the service after mangling. If such profile is not defined, rmw_fastrtps attempts to load a <data_writer> profile with attribute profile_name="service". If neither of the previous profiles exist, rmw_fastrtps attempts to load the <data_writer> profile with attribute is_default_profile="true".

16.1.2.2.3. Creating clients with different profiles

ROS 2 clients contain a publisher to send requests, and a subscription to receive the service’s replies. rmw_fastrtps allows for configuring each of these endpoints separately in the following manner:

  • To configure the requests publisher, define a <data_writer> profile with attribute profile_name=topic_name, where topic_name is the name of the service after mangling. If such profile is not defined, rmw_fastrtps attempts to load a <data_writer> profile with attribute profile_name="client". If neither of the previous profiles exist, rmw_fastrtps attempts to load the <data_writer> profile with attribute is_default_profile="true".

  • To configure the reply subscription, define a <data_reader> profile with attribute profile_name=topic_name, where topic_name is the name of the service after mangling. If such profile is not defined, rmw_fastrtps attempts to load a <data_reader> profile with attribute profile_name="client". If neither of the previous profiles exist, rmw_fastrtps attempts to load the <data_reader> profile with attribute is_default_profile="true".

16.1.2.2.4. Creating ROS contexts and nodes

ROS context and node entities are mapped to Fast DDS Participant entity, according to the following table:

ROS entity

Fast DDS entity since Foxy

Fast DDS entity in Eloquent & below

Context

Participant

Not DDS direct mapping

Node

Not DDS direct mapping

Participant

This means that on Foxy and later releases, contexts can be configured using a <Participant> profile with attribute is_default_profile="true". The same profile will be used in Eloquent and below to configure nodes.

For example, a profile for a ROS 2 context on Foxy and later releases would be specified as:

XML

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com">
    <participant profile_name="participant_profile_ros2" is_default_profile="true">
        <rtps>
            <name>profile_for_ros2_context</name>
        </rtps>
    </participant>
</profiles>

16.1.3. Example

The following example uses the ROS 2 talker/listener demo, configuring Fast DDS to publish synchronously, and to have dynamically allocated publisher and subscriber histories.

  1. Create a XML file ros_example.xml and save it in path/to/xml/

    XML

    <?xml version="1.0" encoding="UTF-8" ?>
    <profiles xmlns="http://www.eprosima.com">
        <participant profile_name="participant_profile_ros2" is_default_profile="true">
            <rtps>
                <name>profile_for_ros2_context</name>
            </rtps>
        </participant>
    
        <!-- Default publisher profile -->
        <data_writer profile_name="default publisher profile" is_default_profile="true">
            <qos>
                <publishMode>
                    <kind>SYNCHRONOUS</kind>
                </publishMode>
            </qos>
            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
        </data_writer>
    
        <!-- Default subscriber profile -->
        <data_reader profile_name="default subscriber profile" is_default_profile="true">
            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
        </data_reader>
    
        <!-- Publisher profile for topic helloworld -->
        <data_writer profile_name="helloworld">
            <qos>
                <publishMode>
                    <kind>SYNCHRONOUS</kind>
                </publishMode>
            </qos>
        </data_writer>
    
        <!-- Request subscriber profile for services -->
        <data_reader profile_name="service">
            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
        </data_reader>
    
        <!-- Request publisher profile for clients -->
        <data_writer profile_name="client">
            <qos>
                <publishMode>
                    <kind>ASYNCHRONOUS</kind>
                </publishMode>
            </qos>
        </data_writer>
    
        <!-- Request subscriber profile for server of service "add_two_ints" -->
        <data_reader profile_name="rq/add_two_intsRequest">
            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
        </data_reader>
    
        <!-- Reply subscriber profile for client of service "add_two_ints" -->
        <data_reader profile_name="rr/add_two_intsReply">
            <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
        </data_reader>
    </profiles>
    
  2. Open one terminal and run:

    export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
    export FASTDDS_DEFAULT_PROFILES_FILE=path/to/xml/ros_example.xml
    export RMW_FASTRTPS_USE_QOS_FROM_XML=1
    ros2 run demo_nodes_cpp talker
    
  3. Open one terminal and run:

    export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
    export FASTDDS_DEFAULT_PROFILES_FILE=path/to/xml/ros_example.xml
    export RMW_FASTRTPS_USE_QOS_FROM_XML=1
    ros2 run demo_nodes_cpp listener
    

16.2. Use ROS 2 with Fast-DDS Discovery Server

This section explains how to run some ROS 2 examples using the Discovery Servers as discovery communication. In order to get more information about the specific use of this configuration, please check the Discovery Server Documentation or read the common use cases for this configuration.

The following tutorial gathers the steps to check this functionality and learn how to use it with ROS 2.

The Simple Discovery Protocol is the standard protocol defined in the DDS standard. However, it has certain known disadvantages in some scenarios, mainly:

  • It does not Scale efficiently, as the number of exchanged packets highly increases as new nodes are added.

  • It requires Multicasting capabilities that may not work reliably in some scenarios, e.g. WiFi.

The Discovery Server provides a Client-Server Architecture that allows the nodes to connect with each other using an intermediate server. Each node will work as a Client, sharing its info with the Discovery Server and receiving the discovery information from it. This means that the network traffic is highly reduced in big systems, and it does not require Multicasting.

_images/ds_explanation.svg

These Discovery Servers can be independent, duplicated or connected with each other in order to create redundancy over the network and avoid having a Single-Point-Of-Failure.

16.2.1. Discovery Server v2

The new version v2 of Discovery Server, available from Fast DDS v2.0.2, implements a new filter feature that allows to further reduce the number of discovery messages sent. This version uses the topic of the different nodes to decide if two nodes must be connected, or they could be left unmatched. The following schema represents the decrease of the discovery packages:

_images/ds1vs2.svg

This architecture reduces the number of packages sent between the server and the different clients dramatically. In the following graph, the reduction in traffic network over the discovery phase for a RMF Clinic demo use case, is shown:

_images/discovery_server_v2_performance.svg

In order to use this functionality, Fast-DDS Discovery Server can be set using the XML configuration for Participants. Furthermore, Fast DDS provides an easier way to set a Discovery Server communication using the fastdds CLI tool and an environment variable, which are going to be used along this tutorial. For a more detailed explanation about the configuration of the Discovery Server, visit Discovery Server Settings.

16.2.2. Prerequisites

This tutorial assumes you have at least a working Foxy ROS 2 installation. In case your installation is using a Fast DDS version lower than v2.0.2 you could not use the fastdds tool. You could update your repository to use a different Fast DDS version, or set the discovery server by Fast-DDS XML QoS configuration.

Note

This tutorial can also be run in Galactic exporting the environment variable that selects Fast DDS as the middleware layer:

export RMW_IMPLEMENTATION=rmw_fastrtps_cpp

16.2.3. Run the demo

The talker-listener ROS 2 demo allows to create a talker node that publishes a Hello World message every second, and a listener node that listens to these messages.

By Sourcing ROS 2 you will get access to the CLI of Fast DDS: fastdds. This CLI gives access to the discovery tool, which allows to launch a server. This server will manage the discovery process for the nodes that connect to it.

Important

Do not forget to source ROS 2 in every new terminal opened.

16.2.3.1. Setup Discovery Server

Start by launching a server with port 11811 and listening on all available interfaces, which is the default configuration for the fastdds CLI tool.

Open a new terminal and run:

fastdds discovery
16.2.3.2. Launch node listener

Execute the listener demo, that will listen in /chatter topic.

In a new terminal, set the environment variable ROS_DISCOVERY_SERVER to use Discovery Server. (Do not forget to source ROS 2 in every new terminal)

export ROS_DISCOVERY_SERVER=127.0.0.1:11811

Afterwards, launch the listener node. Use the argument --remap __node:=listener_discovery_server to change the node’s name for future purpose.

ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_discovery_server

This process will create a ROS 2 node, that will automatically create a client for the Discovery Server and use the server created previously to run the discovery protocol.

16.2.3.3. Launch node talker

Open a new terminal and set the environment variable as before, so the node raises a client for the discovery protocol.

export ROS_DISCOVERY_SERVER=127.0.0.1:11811
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_discovery_server

Now, we should see the talker publishing Hello World messages, and the listener receiving these messages.

16.2.3.4. Demonstrate Discovery Server execution

So far, there is not proof that this example and the standard talker-listener example run differently. For this purpose, run another node that is not connected to our Discovery Server. Just run a new listener (listening in /chatter topic by default) in a new terminal and check that it is not connected to the talker already running.

ros2 run demo_nodes_cpp listener --ros-args --remap __node:=simple_listener

In this case, we should not see the listener receiving the messages.

To finally verify that everything is running correctly, a new talker can be created using the simple discovery protocol.

ros2 run demo_nodes_cpp talker --ros-args --remap __node:=simple_talker

Now we should see the listener simple_listener receiving the messages from simple_talker but not the other messages from talker_discovery_server.

16.2.4. Advance user cases

The following paragraphs are going to show different features of the Discovery Server that allows to hold a robust structure over the node’s network.

16.2.4.1. Server Redundancy

By using the Fast DDS tool, several servers can be created, and the nodes can be connected to as many servers as desired. This allows to have a safe redundancy network that will work even if some servers or nodes shut down unexpectedly. Next schema shows a simple architecture that will work with server redundancy:

_images/ds_redundancy_example.svg

In different terminals, run the next code to establish a communication over redundant servers.

fastdds discovery -l 127.0.0.1 -p 11811
fastdds discovery -l 127.0.0.1 -p 11888
export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker
export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener

Now, if one of these servers fails, there would still be discovery communication between nodes.

16.2.4.2. Backup Server

Fast DDS Discovery Server allows to easily build a server with a backup functionality. This allows the server to retake the last state it saved in case of a shutdown.

_images/ds_backup_example.svg

In different terminals, run the next code to establish a communication over a backup server.

fastdds discovery -l 127.0.0.1 -p 11811 -b
export ROS_DISCOVERY_SERVER="127.0.0.1:11811"
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker
export ROS_DISCOVERY_SERVER="127.0.0.1:11811"
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener

Several backup files are created in the path the server has run. Two SQLite files and two json files that contains the information required to raise a new server in case of failure, avoiding the whole discovery process to happen again and without losing information.

16.2.4.3. Discovery partitions

The Discovery Server communication could be used with different servers to split in virtual partitions the discovery info. This means that two endpoints only would know each other if there is a server or a server network between them. We are going to execute an example with two different independent servers. The following image shows a schema of the architecture desired:

_images/ds_partition_example.svg

With this schema Listener 1 will be connected to Talker 1 and Talker 2, as they share Server 1. Listener 2 will connect with Talker 1 as they share Server 2. But Listener 2 will not hear the messages from Talker 2 because they do not share any server or servers’ network that connect them.

Run the first server listening in localhost on default port 11811.

fastdds discovery -l 127.0.0.1 -p 11811

In another terminal run the second server listening in localhost on another port, in this case 11888.

fastdds discovery -l 127.0.0.1 -p 11888

Now, run each node in a different terminal. Use the environment variable ROS_DISCOVERY_SERVER to decide which server they are connected to.

export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_1
export ROS_DISCOVERY_SERVER="127.0.0.1:11811;127.0.0.1:11888"
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_1
export ROS_DISCOVERY_SERVER="127.0.0.1:11811"
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker_2
export ROS_DISCOVERY_SERVER=";127.0.0.1:11888"
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener_2

We should see how Listener 1 is receiving double messages, while Listener 2 is in a different partition from Talker 2 and so it does not listen to it.

Note

Once two endpoints know each other, they do not need the server network between them to listen to each other messages.

16.2.5. ROS 2 Introspection

ROS 2 Command Line Interface (CLI) implements several introspection features to analyze the behaviour of a ROS 2 execution. These features (i.e. rosbag, topic list, etc.) are very helpful to understand a ROS 2 working network.

Most of these features use the DDS capability to share any topic information with every exiting participant. However, the new Discovery Server v2 implements a traffic network reduction that limits the discovery data between nodes that do not share a topic. This means that not every node will receive every topic data unless it has a reader in that topic. As most of ROS 2 CLI Introspection is executed by adding a node into the network (some of them use ROS 2 Daemon, and some create their own nodes), using Discovery Server v2 we will find that most of these functionalities are limited and do not have all the information.

The Discovery Server v2 functionality allows every node running as a SUPER_CLIENT, a kind of Client that connects to a SERVER, from which it receives all the available discovery information (instead of just what it needs). In this sense, ROS 2 introspection tools can be configured as Super Client, thus being able to discover every entity that is using the Discovery Server protocol within the network.

16.2.5.2. No Daemon commands

Some ROS 2 CLI tools can be executed without the ROS 2 Daemon. In order for these tools to connect with a Discovery Server and receive all the topics information they need to be instantiated as a Super Client that connects to the Server.

Following the previous configuration, build a simple system with a talker and a listener. First, run a Server:

fastdds discovery -l 127.0.0.1 -p 11811

Then, run the talker and listener is separate terminals:

export ROS_DISCOVERY_SERVER=127.0.0.1:11811
ros2 run demo_nodes_cpp listener --ros-args --remap __node:=listener
export ROS_DISCOVERY_SERVER=127.0.0.1:11811
ros2 run demo_nodes_cpp talker --ros-args --remap __node:=talker

Continue using the ROS 2 CLI with --no-daemon option with the new configuration. New nodes will connect with the existing Server and will know every topic. Exporting ROS_DISCOVERY_SERVER is not needed as the remote server has been configured in the xml file.

export FASTDDS_DEFAULT_PROFILES_FILE=super_client_configuration_file.xml
ros2 topic list --no-daemon
ros2 node info /talker --no-daemon --spin-time 2

16.2.6. Compare Discovery Server with Simple Discovery

In order to compare the ROS 2 execution using Simple Discovery or Discovery Server, two scripts that execute a talker and many listeners and analyze the network traffic during this time are provided. For this experiment, tshark is required to be installed on your system. The configuration file is mandatory in order to avoid using intra-process mode.

Note

These scripts require a Discovery Server closure feature that is only available from Fast DDS v2.1.0 and forward. In order to use this functionality, compile ROS 2 with Fast DDS v2.1.0 or higher.

These scripts’ functionalities are references for advance purpose and their study is left to the user.

Run the bash script with the setup path to source ROS 2 as argument. This will generate the traffic trace for simple discovery. Executing the same script with second argument SERVER, it will generates the trace for service discovery.

Note

Depending on your configuration of tcpdump, this script may require sudo privileges to read traffic across your network device.

After both executions are done, run the python script to generates a graph similar to the one below:

$ export FASTDDS_DEFAULT_PROFILES_FILE="no_intraprocess_configuration.xml"
$ sudo bash generate_discovery_packages.bash ~/ros2_foxy/install/local_setup.bash
$ sudo bash generate_discovery_packages.bash ~/ros2_foxy/install/local_setup.bash SERVER
$ python3 discovery_packets.py
_images/discovery_packets.svg

This graph is the result of a is a specific example, the user can execute the scripts and watch their own results. It can easily be seen how the network traffic is reduced when using Discovery Service.

The reduction in traffic is a result of avoiding every node announcing itself and waiting a response from every other node in the net. This creates a huge amount of traffic in large architectures. This reduction from this method increases with the number of Nodes, making this architecture more scalable than the simple one.

Since Fast DDS v2.0.2 the new Discovery Server v2 is available, substituting the old Discovery Server. In this new version, those nodes that do not share topics will not know each other, saving the whole discovery data required to connect them and their endpoints. Notice that this is not this example case, but even though the massive reduction could be appreciate due to the hidden architecture topics of ROS 2 nodes.

17. RPC over DDS

Remote Procedure Calls (see RPC over DDS specification), also known as RPC, is a type of bidirectional communication used in a request-reply pattern. The RPC architecture is based on the client-server model: the client sends a request to the server, and the server sends one or more responses (replies) back to the client. In the context of Data Distribution Service (DDS), the client and server are modeled using DomainParticipants and they contain all the necessary objects to communicate with each other. Each client (internally represented by a Requester entity) sends a request sample to the server through a request topic; the server (internally represented by a Replier entity) processes it and sends a reply sample back to the client through a different topic (reply topic). All the Requesters and Repliers internally have a DataWriter and DataReader to send and receive samples.

17.1. RPC over DDS Request-Reply API overview

Fast DDS DomainParticipant provides a high-level Request-Reply API to create all the DDS entities required for RPC over DDS communication. The API provides methods for creating and deleting three types of entities:

  • Service: Represents the subset of DDS entities associated with a DomainParticipant that participate in the same RPC Request/Reply communication. This includes the topics where Requests and Replies are published and the endpoints responsible for publishing and receiving Requests and Replies, which are grouped in Requesters and Repliers.

  • Requester: Represents the subset of DDS entities, associated with a Service instance, responsible for processing samples on the client side. This includes a DataWriter for publishing Request samples and a DataReader for receiving Reply samples.

  • Replier: Represents the subset of DDS entities, associated with a Service instance, responsible for processing samples on the server side. This includes a DataWriter for publishing Reply samples and a DataReader for receiving Request samples.

All these entities inherit from the abstract base class RPCEntity, which represents a generic entity in the context of RPC over DDS communication. According to RPC over DDS Standard, each entity has two different states: enabled and disabled. A disabled entity is an entity that has been created but is ignored by the middleware, so it does not participate in the communication.

User can enable and disable an entity using enable() and close() methods, respectively. Internally, when an entity is enabled, the middleware creates the DDS entities associated with it. Similarly, when an entity is disabled, the middleware deletes their DDS entities.

Note

Trying to use an RPC entity (Requester or Replier) for RPC communication when it is disabled will return an error. The user can check if an entity is enabled using is_enabled() method.

To match a request with a reply, Requesters and Repliers use a correlation mechanism. When a Request sample is sent, Requester associates a unique identifier to it represented by RequestInfo struct.

This identifier contains a SampleIdentity instance, which is formed by the Requester’s DataWriter Guid_t and a sequence number, and can be accessed through related_sample_identity member. When a Replier takes a new received Request sample, it extracts the related_sample_identity information and uses it to create a new RequestInfo which is then associated to the Reply sample.

RequestInfo works like a way to match a Reply with a previously sent Request: when a Requester receives a Reply sample, correlation of Requests and Replies is done by comparing both RequestInfo instances. If they are the same, the Reply sample is associated with the Request sample.

A request/reply communication can be established between different DomainParticipants on the same domain if they have Requesters and Repliers in the same Service. In a multiple Requester scenario (for example, one Requester per DomainParticipant), reply samples sent by each Replier will be received by all Requester’s DataReaders, whether it corresponds to a request sample sent by its associated Requester or not. Replier adds to each reply sample the Guid_t of the DataWriter which sent its associated request sample, so reply samples are filtered on Requester side creating a ContentFilteredTopic from the Reply Topic. The content filtered topic filters reply samples comparing the DataReader’s GuidPrefix_t with the GuidPrefix_t of the received related_sample_identity, so only replier samples associated to request samples sent by the same DomainParticipant are received. When a Requester is created, its DataReader is created from this ContentFilteredTopic instance.

17.1.1. RPC Service

A Service is the RPCEntity used to register all RPCEntities involved in an RPC communication, both on the client side (Requesters) and on the server side (Repliers). Two or more participants can communicate with each other via RPC if they register the same service and create Requesters and Repliers in it.

A service is represented by its name and a Service type, so that two Service instances represent the same RPC service if they have the same name and type. The name of the Service and the name of its type can be obtained through the methods get_service_name() and get_service_type_name() respectively.

Similarly to the rest of the RPC entities, Service instances can be enabled or disabled, according to whether they contain DDS entities or not:

  • Each active Service contains at least two DDS entities: a Request Topic, which is used to publish and receive Request samples, and a Reply Topic, which is used to publish and receive Reply samples. If it also contains enabled Requesters and Repliers, it also includes their respective internal DataWriters and DataReaders. Therefore, an enabled Service instance can also be understood as the subset of DDS entities associated with a DomainParticipant that participate in the same communication through RPC.

  • Each disabled Replier does not contain any DDS entity and is ignored by the middleware. Therefore, it cannot take requests nor send replies.

17.1.1.1. Service types

Due to the fact that a Service represents a Request/Reply communication, a Service type is represented by a pair of topic types: the Request topic type and the Reply topic type. A new Service type can be defined creating an instance of ServiceTypeSupport class, which is constructed using TypeSupport instances of both Request and Reply types.

DomainParticipant class have register_service_type() and unregister_service_type() methods to register and unregister a ServiceTypeSupport instance, respectively.

Note

Request and Reply types associated with a service type named <service_type_name> are registered in the participant with the names <service_type_name>_Request` and <service_type_name>_Reply, respectively.

A registered ServiceTypeSupport can be found by name using find_service_type() method; if a Service type with the provided name is not found, an empty ServiceTypeSupport is returned.

Note

Trying to register a different ServiceTypeSupport instance with a service_type_name already registered will return a ReturnCode_t error.

Registering and unregistering a ServiceTypeSupport instance involves registering and unregistering the Request and Reply types in the participant, respectively. If a ServiceTypeSupport contains a Request or Reply type with the same name as a previously registered type but with a different TypeSupport, the register_service_type() method will fail. Similarly, attempting to unregister a ServiceTypeSupport instance with a Request or Reply type that is used by a DDS endpoint on a topic not created by the Service will fail. To avoid these issues, it is recommended to make sure that the Request and Reply types are reserved for RPC communication though a unique service and not used by external DDS entities which are not part of the Service.

17.1.1.2. Creating and deleting a Service

A DomainParticipant can create and register a Service instance using DomainParticipant::create_service() method. Respectively, a Service can be unregistered and deleted using DomainParticipant::delete_service() method. Each registered Service can be found by name using DomainParticipant::find_service() method.

Note

Before creating a new Service, user must register the ServiceTypeSupport instance associated with the Service type. If there is no Service type registered with the service_type_name provided, Service is not created and DomainParticipant::create_service() method will return a null pointer.

When a new Service is created, it is enabled by default. It means that DomainParticipant creates the topics used for publishing and receiving Request and Reply samples.

Note

If the DomainParticipant is unable to enable the Service when it is created, it is considered an error. The instance is destroyed, and DomainParticipant::create_service() returns nullptr.

Only the DomainParticipant that created the Service instance can delete it. Attempting to delete a Service instance from a different DomainParticipant will result in a ReturnCode_t error.

17.1.1.3. Enabling and disabling a Service

Service instances can be enabled or disabled using enable() and close() methods, respectively.

When a disabled Service instance is enabled, new Request and Reply topics are created in the DomainParticipant using the registered Service type. It also creates the content filtered topic used for Reply samples. Additionally, if it contains Requesters and Repliers, an attempt will be made to enable all possible entities.

Note

Request and Reply topics are created with names <service_name>_Request and <service_name>_Reply, respectively. The ContentFilteredTopic instance is also created from the Reply topic instance with name <service_name>_ReplyFiltered.

Note

If some of the RPCEntities within the Service cannot be enabled, an error log is displayed. However, enable() ignores this failure and returns RETCODE_OK` as long as the topics have been created successfully.

Reciprocally, when an enabled Service is disabled, all the DDS entities that the Service contains are destroyed, making the Service not participate in the communication through RPC. It implies disabling all containing Requesters and Repliers and deleting the Request and Reply topics.

Note

If some of the RPCEntities within the Service cannot be disabled, close() returns an error code.

17.1.1.4. Example

The following code snippet shows how to create and delete a Service instance:

        TypeSupport request_type_support = TypeSupport(new CustomDataType());
        TypeSupport reply_type_support = TypeSupport(new CustomDataType());
        DomainParticipant* participant =
            DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);

        // Create a new ServiceTypeSupport instance
        ServiceTypeSupport service_type_support(request_type_support, reply_type_support);

        // Register the ServiceTypeSupport instance in a DomainParticipant
        ReturnCode_t ret;
        ret = participant->register_service_type(service_type_support, "ServiceType");
        if (RETCODE_OK != ret)
        {
            // Error
            return;
        }

        // Create a new Service instance
        Service* service = participant->create_service("Service", "ServiceType");
        if (!service)
        {
            // Error
            return;
        }

        // ... Create Requesters and Repliers here

        // Delete the created Service
        ret = participant->delete_service(service);
        if (RETCODE_OK != ret)
        {
            // Error
            return;
        }

17.1.2. RPC Requester

A Requester is the RPC Entity used in the communication at the client side, sending Request samples and processing the received Reply samples.

Since each Requester is used in only one Request/Reply communication, represented by a Service, all of them are registered in a Service instance when created. The name of the service associated with a Requester can be accessed using Requester::get_service_name() method.

Similarly to the rest of the RPC entities, Requester instances can be enabled or disabled, according to whether they contain DDS entities or not:

  • Each active Requester contains two DDS entities: a DataWriter, which is used to publish Request samples, and a DataReader, which is used to receive Reply samples.

  • Each disabled Requester does not contain any DDS entity and is ignored by the middleware. Therefore, it cannot send requests nor take replies.

For consistency, the states of each Requester instance and its associated Service must follow the compatibility rule below:

\[requester\_state \leq service\_state\]

where requester_state is the state of the Requester instance and service_state is the state of the associated Service, and the order of the states is defined as \(disabled < enabled\).

17.1.2.1. Creating a Requester

A new Requester instance can be created in an enabled or disabled Service using DomainParticipant::create_service_requester() method. When a new Requester instance is created, it is registered internally in the Service. Each Service can contain multiple Requester instances.

Note

Following the state compatibility rule, calling DomainParticipant::create_service_requester() using a disabled Service instance as input parameter creates a disabled Requester.

Reciprocally, calling DomainParticipant::create_service_requester() with an enabled Service instance tries to return an enabled Requester. If the process of enabling the Requester fails (i.e., the creation of the internal DDS entities), DomainParticipant::create_service_requester() returns nullptr.

All Requester’s DDS entities Qos can be configured manually when creating the Requester instance using RequesterQos. Before creating the Requester, Service validates DataWriterQos and DataReaderQos provided in the RequesterQos instance: if some field is not valid, Service will notify it to the user using a log message error and Requester is not created.

User must ensure that ReliabilityQosPolicyKind of both DataWriter and DataReader are set to RELIABLE_RELIABILITY_QOS. This is configured automatically when a new RequesterQos instance is created.

Note

Before creating a new Requester, user must create its associated Service instance in the DomainParticipant. If a null pointer or a Service associated with a different participant are provided, Requester is not created and DomainParticipant::create_service_requester() method returns a null pointer.

17.1.2.2. Enabling and disabling a Requester

Requester instances can be enabled or disabled using enable() and close() methods, respectively.

When a disabled Requester instance is enabled, a new DataReader on the content filtered Reply topic and a new DataWriter on Request topic are created using the Qos configured at creation through RequesterQos.

User can access to the DataWriter and DataReader instances using Requester::get_requester_writer() and Requester::get_requester_reader() methods, respectively.

Reciprocally, when an enabled Requester is disabled, its respective DataWriter and DataReader are destroyed, making the Requester not participate in the communication through the Service.

Warning

A disabled Requester does not contain DDS entities, so Requester::get_requester_writer() and Requester::get_requester_reader() return a null pointer in this case. The user must be responsible for checking that the Requester is enabled using the is_enabled() method before accessing the Requester’s internal DDS entities.

17.1.2.3. Deleting a Requester

A Requester instance can be unregistered from a Service and deleted using DomainParticipant::delete_service_requester() method.

This method can be called on Requesters in any state: if enabled, it will try to disable the instance, returning a ReturnCode_t error if it was not possible to close the Requester.

Note

If there is no Service with the provided service_name or the Requester is associated with a different Service, DomainParticipant::delete_service_requester() method will return a ReturnCode_t error.

17.1.2.4. Sending and receiving samples

Request samples can be sent using the Requester::send_request() method. When this method is called, the created DataWriter sends a new Request sample with the provided data and fills the related_sample_identity field in the input RequestInfo struct with the Guid_t of the DataWriter and a sequence number.

Similarly, received Reply samples are taken using Requester::take_reply() method. When this method is called, Requester takes received Reply samples from the history of the DataReader and fills the provided RequestInfo struct with the related_sample_identity of the received Reply sample. This way, user can match Request and Reply samples by checking if the related_sample_identity attributes of their RequestInfo instances are equal.

The Requester public API provides two overloads for Requester::take_reply(), depending on whether you want to take only the next sample or all samples from the DataReader history.

Note

In case of using the overload that takes all samples, the loan must be returned to avoid memory problems. The user must therefore be responsible for calling the Requester::return_loan() method after finishing processing the samples.

Warning

If a Request sample is sent before discovering a Replier, the middleware will not be able to deliver the Request sample and will discard it. The endpoint matching algorithm described in RPC over DDS Standard 7.6.2.2 will be implemented in future releases.

Warning

RPC over DDS implementation in Fast DDS is designed to be incompatible with Listeners. If user needs to process status changes, it can be done creating a WaitSet on a different thread.

17.1.2.5. Example

The following code snippet shows how to use a Requester instance:

        ReturnCode_t ret;

        // Get a valid service
        Service* service = participant->find_service("Service");
        if (!service)
        {
            // Error
            return;
        }

        /* Create a new Requester instance */
        RequesterQos requester_qos;

        Requester* requester = participant->create_service_requester(service, requester_qos);
        if (!requester)
        {
            // Error
            return;
        }

        /* Send a new Request sample and check if a received Reply sample is a match */
        // Make sure that all RPC Entities are enabled
        if (!service->is_enabled())
        {
            ret = service->enable();
            if (RETCODE_OK != ret)
            {
                // Error
                return;
            }
        }

        //  Enabling the service enables the registered Requester unless
        //  the creation of the internal DataWriter and DataReader failed.
        //  We can make sure that they have been created correctly by checking if the Requester is enabled.
        if (!requester->is_enabled())
        {
            // Error
            return;
        }

        RequestInfo expected_request_info;
        RequestInfo received_request_info;
        // Create a new Request sample
        void* request_data = request_type_support->create_data();
        ret = requester->send_request(request_data, expected_request_info);
        if (RETCODE_OK != ret)
        {
            // Error
            return;
        }
 
        // Wait for some time until a Reply sample is received
        requester->get_requester_reader()->wait_for_unread_message(Duration_t{3,0});

        void* data = nullptr;
        ret = requester->take_reply(data, received_request_info);
        if (RETCODE_OK != ret)
        {
            // Error
            return;
        }
    
        if (expected_request_info.related_sample_identity == received_request_info.related_sample_identity)
        {
          // Received Reply sample is associated to the sent Request sample
        }
    
        // Delete created Requester
        ret = participant->delete_service_requester(requester->get_service_name(), requester);
        if (RETCODE_OK != ret)
        {
          // Error
          return;
        }

17.1.3. RPC Replier

A Replier is the RPC Entity used in the communication at the server side, processing the received Request samples and sending Reply samples back to the Requester when the result of the operation is ready.

Since each Replier is used in only one Request/Reply communication, represented by a Service, all of them are registered in a Service instance when created. The name of the service associated with a Replier can be accessed using Replier::get_service_name() method.

Similarly to the rest of the RPC entities, Replier instances can be enabled or disabled, according to whether they contain DDS entities or not:

  • Each active Replier contains two DDS entities: a DataWriter, which is used to publish Reply samples, and a DataReader, which is used to receive Request samples.

  • Each disabled Replier does not contain any DDS entity and is ignored by the middleware. Therefore, it cannot take requests nor send replies.

For consistency, the states of each Replier instance and its associated Service must follow the compatibility rule below:

\[replier\_state \leq service\_state\]

where replier_state is the state of the Replier instance and service_state is the state of the associated Service, and the order of the states is defined as \(disabled < enabled\).

17.1.3.1. Creating a Replier

A new Replier instance can be created in an enabled or disabled Service using DomainParticipant::create_service_replier() method. When a new Replier instance is created, it is registered internally in the Service. Each Service can contain multiple Replier instances.

Note

Following the state compatibility rule, calling DomainParticipant::create_service_replier() using a disabled Service instance as input parameter creates a disabled Replier.

Reciprocally, calling DomainParticipant::create_service_replier() with an enabled Service instance tries to return an enabled Replier. If the process of enabling the Replier fails (i.e., the creation of the internal DDS entities), DomainParticipant::create_service_replier() returns nullptr.

All Replier’s DDS entities Qos can be configured manually when creating the Replier instance using ReplierQos. Before creating the Replier, Service validates DataWriterQos and DataReaderQos provided in the ReplierQos instance: if some field is not valid, Service will notify it to the user using a log message error and Replier is not created.

User must ensure that ReliabilityQosPolicyKind of both DataWriter and DataReader are set to RELIABLE_RELIABILITY_QOS. This is configured automatically when a new ReplierQos instance is created.

Note

Before creating a new Replier, user must create its associated Service instance in the DomainParticipant. If a null pointer or a Service associated with a different participant are provided, Replier is not created and DomainParticipant::create_service_replier() method returns a null pointer.

17.1.3.2. Enabling and disabling a Replier

Replier instances can be enabled or disabled using enable() and close() methods, respectively.

When a disabled Replier instance is enabled, a new DataWriter on the Reply topic and a new DataReader on Request topic are created using the Qos configured at creation through ReplierQos.

User can access to the DataWriter and DataReader instances using Replier::get_replier_writer() and Replier::get_replier_reader() methods, respectively.

Reciprocally, when an enabled Replier is disabled, its respective DataWriter and DataReader are destroyed, making the Replier not participate in the communication through the Service.

Warning

A disabled Replier does not contain DDS entities, so Replier::get_replier_writer() and Replier::get_replier_reader() return a null pointer in this case. The user must be responsible for checking that the Replier is enabled using the is_enabled() method before accessing the Replier’s internal DDS entities.

17.1.3.3. Deleting a Replier

A Replier instance can be unregistered from a Service and deleted using DomainParticipant::delete_service_replier() method.

This method can be called on Repliers in any state: if enabled, it will try to disable the instance, returning a ReturnCode_t error if it was not possible to close the Replier.

Note

If there is no Service with the provided service_name or the Replier is associated with a different Service, DomainParticipant::delete_service_replier() method will return a ReturnCode_t error.

17.1.3.4. Sending and receiving samples

Request samples are taken using the Replier::take_request() method. When this method is called, Replier takes received Request samples from the history of the internal DataReader and fills the related_sample_identity member of the provided RequestInfo struct with the related_sample_identity` of the received Request sample.

The Replier public API provides two overloads for Replier::take_request(), depending on whether you want to take only the next sample or all samples from the DataReader history.

Note

In case of using the overload that takes all samples, the loan must be returned to avoid memory problems. The user must therefore be responsible for calling the Replier::return_loan() method after finishing processing the samples.

After processing the Request, Replier sends a new Reply sample using the Replier::send_reply() method and passing the previously created RequestInfo as an input parameter. When Replier::send_reply() method is called, the created DataWriter sends a new Reply sample with the provided data and the related_sample_identity of the Request sample that originated the Reply, to allow Request and Reply samples correlation at the Requester side.

Warning

If a Reply sample is sent before discovering the Requester Reply topic DataReader, the middleware will not be able to deliver the Reply sample and will discard it. The endpoint matching algorithm described in RPC over DDS Standard will be implemented in future releases.

Warning

RPC over DDS implementation in Fast DDS is designed to be incompatible with Listeners. If user needs to process status changes, it can be done creating a WaitSet on a different thread.

17.1.3.5. Example

The following code snippet shows how to use a Replier instance:

        ReturnCode_t ret;

        // Get a valid service
        Service* service = participant->find_service("Service");
        if (!service)
        {
            // Error
            return;
        }

        /* Create a new Replier instance */
        ReplierQos replier_qos;

        Replier* replier = participant->create_service_replier(service, replier_qos);
        if (!replier)
        {
            // Error
            return;
        }

        /* Take a received Request sample and send a new Reply sample */

        // Make sure that all RPC Entities are enabled
        if (!service->is_enabled())
        {
            ret = service->enable();
            if (RETCODE_OK != ret)
            {
                // Error
                return;
            }
        }

        //  Enabling the service enables the registered Replier unless
        //  the creation of the internal DataWriter and DataReader failed.
        //  We can make sure that they have been created correctly by checking if the Replier is enabled.
        if (!replier->is_enabled())
        {
            // Error
            return;
        }

        RequestInfo received_request_info;

        // Wait for some time until a Request sample is received
        replier->get_replier_reader()->wait_for_unread_message(Duration_t{3,0});

        void* received_data = nullptr;

        ret = replier->take_request(received_data, received_request_info);
        if (RETCODE_OK != ret)
        {
            // Error
            return;
        }

        // ... Process received data

        // Send a Reply with the received related_sample_identity
        void* reply_data = reply_type_support->create_data();
        ret = replier->send_reply(reply_data, received_request_info);
        if (RETCODE_OK != ret)
        {
            // Error
            return;
        }

        /* Delete created Replier */
        ret = participant->delete_service_replier(replier->get_service_name(), replier);
        if (RETCODE_OK != ret)
        {
          // Error
          return;
        }

18. Troubleshooting

This section offers hints and pointers to help users with navigating through the documentation while troubleshooting issues.

  • Although UDP/SHM default transports of Fast DDS are designed to work in most network environments, they may encounter certain limitations when operating over WiFi or within lossy network conditions. In these cases, it is advisable to set up the LARGE_DATA configuration, which has been specifically optimized for these scenarios. The LARGE_DATA profile limits the use of UDP solely to the PDP discovery phase, employing the more reliable TCP/SHM for the remainder of the communication process. Its implementation can be accomplished by simply configuring the FASTDDS_BUILTIN_TRANSPORTS environment variable, or alternatively through XML profiles or via code. For more information, please refer to Large Data Mode.

    export FASTDDS_BUILTIN_TRANSPORTS=LARGE_DATA
    
    <?xml version="1.0" encoding="UTF-8" ?>
    <dds xmlns="http://www.eprosima.com">
        <profiles>
            <!--
                UDP transport for PDP and SHM/TCPv4 transport for both EDP and application data
            -->
            <participant profile_name="large_data_builtin_transports" is_default_profile="true">
                <rtps>
                    <builtinTransports>LARGE_DATA</builtinTransports>
                </rtps>
            </participant>
        </profiles>
    </dds>
    
    eprosima::fastdds::dds::DomainParticipantQos pqos = PARTICIPANT_QOS_DEFAULT;
    
    /* Transports configuration */
    // UDPv4 transport for PDP over multicast and SHM / TCPv4 transport for EDP and application data
    pqos.setup_transports(eprosima::fastdds::rtps::BuiltinTransports::LARGE_DATA);
    
    /* Create participant as usual */
    eprosima::fastdds::dds::DomainParticipant* participant =
            eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(0, pqos);
    
  • If having problems with transmitting large samples when using the LARGE_DATA mode, try to use the builtin transports configuration options to adjust LARGE_DATA to your specific use case. Please refer to Large Data with configuration options for more information.

  • If having problems with transmitting large samples such as video or point clouds, please refer to Large Data Rates.

  • Fast DDS v3 introduced the new feature XTypes, which allows to discover remote types. In consequence, discovery traffic can be increased during start up. If you are experiencing high load during discovery, try disabling the new feature. Please refer to disable type propagation to learn how to do it.

19. Frequently Asked Questions

This section answers to frequently asked questions about FastDDS.

19.1. Frequently Asked Getting Started Questions

What is DDS?


The Data Distribution Service (DDS) is a data-centric communication protocol used for distributed software application communications. For further information, refer to What is DDS?.


What are the key entities of a DDS?


These are the basic entities of a DDS: Publisher, Subscriber, DataReader, DataWriter, Topic, domain. For further information, refer to What is DDS?.


What is the primary purpose of using Quality of Service (QoS) in DDS?


DDS uses QoS to define the behavioral characteristics of DDS Entities. QoS are comprised of individual QoS policies (objects of type deriving from QoSPolicy). For further information, refer to What is DDS?.


What is the primary responsibility of a DDS Publisher entity?


Publisher. It is the Data-Centric Publish Subscribe entity in charge of the creation and configuration of the DataWriters it implements. The DataWriter is the entity in charge of the actual publication of the messages. Each one will have an assigned Topic under which the messages are published. For further information, refer to Publisher.


What is the primary responsibility of a DDS Subscriber entity?


Subscriber. It is the DCPS Entity in charge of receiving the data published under the topics to which it subscribes. It serves one or more DataReader objects, which are responsible for communicating the availability of new data to the application. For further information, refer to Subscriber.


What is the primary function of a DDS Domain?


domain. This is the concept used to link all publishers and subscribers, belonging to one or more applications, which exchange data under different topics. These individual applications that participate in a domain are called DomainParticipant. The DDS Domain is identified by a domain ID. Domains create logical separations among the entities that share a common communication infrastructure. They isolate applications running in the same domain from applications running on different domains. For further information, refer to Domain.


What is RTPS?


The Real-Time Publish Subscribe (RTPS) protocol, developed to support DDS applications, is a publication-subscription communication middleware over transports such as UDP/IP. RTPS supports unicast and multicast communications, organizing communication within independent domains containing RTPSParticipants, which use RTPSWriters to send data and RTPSReaders to receive data, all centered around Topics that label exchanged data. For further information, refer to What is RTPS?.


What type of communication does RTPS support?


It is designed to support both unicast and multicast communications. For further information, refer to What is RTPS?.


What is the maximum number of endpoints that a single RTPSParticipant can have?


A RTPSParticipant can have any number of writer and reader endpoints. For further information, refer to What is RTPS?.


What is the primary mechanism by which RTPS participants exchange data, and what role do topics play in this process?


Communication revolves around Topics, which define and label the data being exchanged. The topics do not belong to a specific participant. The participant, through the RTPSWriters, makes changes in the data published under a topic, and through the RTPSReaders receives the data associated with the topics to which it subscribes. The communication unit is called Change, which represents an update in the data that is written under a Topic. RTPSReaders/RTPSWriters register these changes on their History, a data structure that serves as a cache for recent changes. For further information, refer to What is RTPS?.


19.2. DDS LAYER Frequently Asked Questions

19.2.1. CORE

19.2.1.1. Entity
What is the significance of a unique ID in the context of DDS and RTPS entities, and why is it important to have a shared ID between these entities?


The unique ID ensures that each entity within the distributed system can be distinctly identified. This is crucial for maintaining the integrity and consistency of communications and operations within the system. By having a shared ID between DDS (Data Distribution Service) and RTPS (Real-Time Publish-Subscribe) entities, the system can seamlessly map and correlate data across different communication protocols and frameworks. For further information refer to Entity.


How does the shared ID between DDS and RTPS entities facilitate communication and interoperability within a distributed system?


A shared ID between DDS and RTPS entities enables a unified reference point for entities involved in communication. This facilitates interoperability by allowing different components and services within the distributed system to easily recognize and interact with each other based on their unique identifiers, thus simplifying the integration and coordination processes. For further information refer to Entity.


In what ways does storing the ID on an Instance Handle object and declaring it on the Entity base class adhere to principles of object-oriented design, such as encapsulation and inheritance?


Storing the ID on an Instance Handle object and declaring it on the Entity base class adheres to encapsulation by keeping the ID management within a dedicated object. This design also leverages inheritance, allowing derived classes to inherit the ID-related functionality from the base class, promoting code reuse and reducing redundancy. For further information refer to Entity.


How might the ability to access the unique ID via the "get_instance_handle()" function influence the implementation and maintenance of a distributed system?


The ability to access the unique ID via the get_instance_handle() function simplifies the implementation and maintenance of the system. Developers can uniformly manage entity identification across various parts of the system, making it easier to track, debug, and update entity-related code. For further information refer to Entity.


What are the advantages and potential drawbacks of using listeners for asynchronous notifications in a DDS system, and how can these drawbacks be mitigated?


Listeners provide real-time notifications of status changes, improving responsiveness and allowing for event-driven programming. However, drawbacks include the potential for increased complexity and resource contention. Mitigation strategies involve keeping listener functions simple and offloading heavy processing to other parts of the system. For further information refer to Entity.


How does the inheritance of listener interfaces across different entity types enhance the flexibility and modularity of the system?


The inheritance of listener interfaces enhances flexibility by allowing different entity types to share common callback mechanisms while enabling customization for specific types. This modularity simplifies code management and fosters reuse. For further information refer to Entity.


How does the limitation of operations on disabled entities influence the design and implementation of a DDS-based system?


Disabled entities can only perform basic operations such as QoS and listener management, status querying, and subentity creation/deletion. This restriction ensures that incomplete or improperly configured entities do not adversely impact the system. For further information refer to Entity.



In what ways do these custom callbacks differ from standard DDS callbacks, and what additional capabilities do they provide to the application developers?


Unlike standard DDS callbacks, Fast DDS custom callbacks are always enabled and offer functionality tailored to the Fast DDS implementation. They provide more granular control over participant and data discovery processes, enhancing the application’s ability to react to dynamic changes. For further information refer to Entity.


19.2.1.2. Policy
How do QoS policies influence the behavior of DDS entities, and what are the potential impacts of misconfiguring these policies on system performance and reliability?


QoS policies determine the operational parameters of DDS entities, such as latency, reliability, and resource usage. Misconfigured QoS policies can lead to suboptimal performance, such as increased latency, dropped messages, or excessive resource consumption, which can negatively affect the overall system reliability and efficiency. For further information refer to Policy.


In what scenarios might it be necessary to modify the QoS policies of an entity after its creation, and what are the best practices for doing so using the "set_qos()" function?


Scenarios necessitating QoS modification post-creation include changes in network conditions, evolving application requirements, or the need to optimize performance. Best practices include using the set_qos() function judiciously, validating the new policies before applying them, and monitoring the system for any adverse effects after changes. For further information refer to DomainParticipant.


What are the implications of creating DDS entities in an enabled or disabled state, and how does the EntityFactoryQosPolicy affect this process?


Creating entities in an enabled state allows for immediate operation, while disabled entities require explicit enabling before full functionality. The EntityFactoryQosPolicy governs this behavior, affecting initial system configuration and operational readiness. For further information refer to EntityFactoryQosPolicy.


How do the specific callbacks provided by Fast DDS, such as on_participant_discovery and on_data_writer_discovery, enhance the functionality of the DDS system?


Fast DDS-specific callbacks, such as on_participant_discovery and on_data_writer_discovery, provide additional hooks for monitoring and responding to specific events within the DDS framework. These callbacks offer greater control and insight into the system’s operational state. For further information refer to Entity.


How does the DeadlineQoS policy apply differently to topics with keys compared to those without keys, and what are the practical considerations for using keys in such scenarios?


For topics with keys, the DeadlineQosPolicy is applied individually to each key. This means that each unique key (e.g., each vehicle in a fleet) must meet its deadline. The practical consideration is that the publisher must manage deadlines for multiple keys simultaneously, which can be complex but allows for more granular control over data timeliness. For further information refer to Standard QoS Policies.


Why is it crucial for the offered deadline period on DataWriters to be less than or equal to the requested deadline period on DataReaders, and what could be the consequences of mismatched periods?


The requirement for the offered deadline period on DataWriters to be less than or equal to the requested deadline period on DataReaders ensures that the DataWriter can meet the DataReader’s expectations. Mismatched periods could result in the DataReader perceiving missed deadlines, leading to potential data loss and reliability issues. For further information refer to Compatibility Rule.


Why is it crucial for the offered deadline period on DataWriters to be less than or equal to the requested deadline period on DataReaders, and what could be the consequences of mismatched periods?


The requirement for the offered deadline period on DataWriters to be less than or equal to the requested deadline period on DataReaders ensures that the DataWriter can meet the DataReader’s expectations. Mismatched periods could result in the DataReader perceiving missed deadlines, leading to potential data loss and reliability issues. For further information refer to Compatibility Rule.


How should the DeadlineQosPolicy be configured in conjunction with the TimeBasedFilterQosPolicy to ensure consistency and avoid data loss or delays?


To ensure consistency, the DeadlineQosPolicy period must be greater or equal to the minimum separation specified in the TimeBasedFilterQosPolicy. This prevents the system from attempting to enforce a stricter deadline than the filter allows, avoiding unnecessary alarms and ensuring smooth data flow. For further information refer to TimeBasedFilterQosPolicy.


How does the default value of c_TimeInfinite for the period in DeadlineQoS affect the behavior of DataWriters and DataReaders, and under what circumstances might this default value be modified?


The default value of c_TimeInfinite means that there is no deadline, so DataWriters and DataReaders are not constrained by time. This is useful for applications where timeliness is not critical. However, for time-sensitive applications, this default should be changed to a specific duration to ensure timely data updates. For further information refer to DeadlineQosPolicy.


What are the key differences between BY_RECEPTION_TIMESTAMP and BY_SOURCE_TIMESTAMP in DestinationOrderQoS, and how do these settings impact the consistency and order of received data?


BY_RECEPTION_TIMESTAMP orders data based on when it is received, which can lead to different DataReaders having different final values due to network delays. BY_SOURCE_TIMESTAMP ensures consistency across all DataReaders by using the send time from the DataWriter. BY_SOURCE_TIMESTAMP is preferred for ensuring consistent data states across multiple DataReaders. Both can be configured by using DestinationOrderQosPolicyKind. For further information refer to DestinationOrderQosPolicy.


In what scenarios might the BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS be preferred over BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS, and vice versa?


BY_RECEPTION_TIMESTAMP might be preferred in scenarios where the most recent data is always the most relevant, regardless of source time (e.g., real-time sensor data). BY_SOURCE_TIMESTAMP is ideal for applications requiring consistency, such as financial transactions or coordinated control systems. For further information refer to DestinationOrderQosPolicyKind.


What are the potential challenges and solutions when DataWriters and DataReaders have incompatible DestinationOrderQoS kinds, and how does the compatibility rule ensure proper data ordering?


Incompatible kinds can lead to data being ignored or reordered incorrectly, causing inconsistencies. The compatibility rule ensures that the DataReader can handle the ordering provided by the DataWriter. Solutions include aligning QoS settings across DataWriters and DataReaders and using appropriate fallback mechanisms. For further information refer to Compatibility Rule.


How might the DestinationOrderQoS policy be applied in a multi-DataWriter scenario to ensure data consistency, and what are the potential pitfalls to avoid?


In scenarios with multiple DataWriters, such as collaborative robotics or distributed simulations, the DestinationOrderQosPolicy ensures that data from different writers is correctly ordered. Avoiding pitfalls like network-induced delays involves carefully configuring timestamps and ensuring synchronized clocks across systems. For further information refer to DestinationOrderQosPolicy.


19.2.1.3. Status
What role do status objects play in the communication lifecycle of DDS entities, and how do they interact with listener callbacks to notify applications of status changes?


Status objects track the communication state of entities, triggering listener callbacks when changes occur. This mechanism ensures that applications are promptly informed of relevant status updates, facilitating timely responses to communication events. For further information refer to Status.



How does the use of StatusMask in enabling or disabling specific callbacks affect the responsiveness and behavior of a DDS system?


The StatusMask allows selective enabling or disabling of specific callbacks, fine-tuning the system’s responsiveness and avoiding unnecessary processing. Proper management of StatusMask settings ensures that only relevant events trigger callbacks, optimizing system behavior. For further information refer to Status.


19.2.2. DOMAIN

Which are the mandatory arguments to create a DomainParticipant?


The mandatory arguments to create a DomainParticipant are the DomainId that identifies the domain where the DomainParticipant will be created and the DomainParticipantQos describing the behavior of the DomainParticipant. If the provided value is TOPIC_QOS_DEFAULT, the value of the DomainParticipantQos is used. For further information refer to Creating a DomainParticipant.


What is the purpose of providing a "DomainId" when creating a DomainParticipant?


The DomainId identifies the domain where the DomainParticipant will be created. Do not use DomainId higher than 200. Once created the DomainParticipant, its DomainId can not be changed. For further information refer to Domain.


What is the purpose of providing a Listener when creating a DomainParticipant?


A Listener derived from DomainParticipantListener, implementing the callbacks that will be triggered in response to events and state changes on the DomainParticipant. By default, empty callbacks are used. For further information about DomainParticipantListener and how to implement its callbacks refer to DomainParticipantListener.


What is the purpose of providing a "StatusMask" when creating a DomainParticipant?


A StatusMask that activates or deactivates triggering of individual callbacks on the DomainParticipantListener. By default, all events are enabled. For further information refer to DomainParticipantListener.


What happens when "create_participant_with_profile()" returns a null pointer in creating a DomainParticipant?


create_participant_with_profile() will return a null pointer if there was an error during the operation, e.g., if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer. For further information refer to Creating a DomainParticipant.


What is the primary way to create a Publisher in the context of DomainParticipant?


A Publisher always belongs to a DomainParticipant. Creation of a Publisher is done with the create_publisher() member function on the DomainParticipant instance. For further information refer to Creating a Publisher.


What settings are used in the creation of a DomainParticipant?


If there is an XML profile exported in the environment, those settings will be used. If the profile has not been exported, the DomainParticipant will be created with the default values per DomainParticipantQos and 0 as DomainId. For further information refer to Default profile DomainParticipant creation.


Why am I unable to delete a DomainParticipant?


To delete a DomainParticipant, it is necessary to delete first all its associated entities to this DomainParticipant. Otherwise, the function will issue an error and the DomainParticipant will not be deleted. To delete the entities, the delete_contained_entities member function must be used, or the entities must be deleted individually. For further information refer to Deleting a DomainParticipant.


How do I modify the behavior of a DomainParticipant?


To modify the behavior of a DomainParticipant, the QoS values specified in the DomainParticipantQos. These QoS values can be set at the creation of the DomainParticipant or modified with the DomainParticipant::set_qos() member function. For further information refer to DomainParticipant.


Under what circumstances does calling "ignore_participant()" member of a DomainParticipant cause deadlock?


When calling ignore_participant inside the listener. This should be used only when there is a need to ignore participants inside the discovery callback. For further information refer to DomainParticipantListener.


19.2.3. PUBLISHER

What is the purpose of providing a PublisherQos when creating a Publisher?


The PublisherQos describes the behavior of the Publisher. If the provided value is PUBLISHER_QOS_DEFAULT, the value of the default PublisherQos is used. For further information refer to PublisherQos.


What is the purpose of providing a Listener when creating a Publisher?


A Listener derived from PublisherListener, implementing the callbacks that will be triggered in response to events and state changes on the Publisher. By default, empty callbacks are used. For further information refer to PublisherListener.


What happens when "create_publisher()" returns a null pointer during the creation of a Publisher?


create_publisher() will return a null pointer if there was an error during the operation, e.g., if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer. This also applies to Subscriber and Topic. For further information refer to Creating a Publisher.


What is the purpose of the "StatusMask" in creating a Publisher or a Subscriber or a Topic?


A StatusMask that activates or deactivates triggering of individual callbacks on the Publisher/Subscriber/Topic listener. By default, all events are enabled. For further information refer to Creating a Publisher.


What happens when "create_publisher_with_profile()" returns a null pointer?


create_publisher_with_profile() will return a null pointer if there was an error during the operation, e.g., if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer. This is also valid for Subscribers. For further information refer to Profile based creation of a Publisher.


What happens when "create_datawriter_with_profile()" returns a null pointer in creating a DataWriter?


create_datawriter_with_profile() will return a null pointer if there was an error during the operation, e.g., if the provided QoS is not compatible or is not supported. It is advisable to check that the returned value is a valid pointer. This is also valid for DataReaders. For further information refer to Profile based creation of a DataWriter.


What is an efficient way to write large data types in DDS using a DataWriter to minimize memory usage and processing time?


An efficient way to write large data types in DDS is to make the DataWriter loan a sample from its memory to the user, and the user to fill this sample with the required values. When write() is called with such a loaned sample, the DataWriter does not copy its contents, as it already owns the buffer. For further information refer to Borrowing a data buffer.


What happens to the contents of a loaned data sample after "write()" has been successfully called with that sample?


Once write() has been called with a loaned sample, the loan is considered returned, and it is not safe to make any changes on the contents of the sample. For further information refer to Borrowing a data buffer.


What happens if a loaned data sample is not written by the user?


If function loan_sample() is called but the sample is never written, the loan must be returned to the DataWriter using discard_loan(). Otherwise, the DataWriter may run out of samples. For further information refer to Borrowing a data buffer.


Why am I unable to delete a Publisher?


To delete a Publisher, it is necessary to delete first all its associated entities. Otherwise, the function will issue an error and the Publisher will not be deleted. To delete the entities, the delete_contained_entities() member function must be used. This is also valid for Subscribers. For further information refer to Deleting a Publisher.


What is the meaning of the value "DATAWRITER_QOS_DEFAULT"?


The value DATAWRITER_QOS_DEFAULT has different meanings depending on where it is used. This is also applicable for the DATAWRITER_QOS_DEFAULT and TOPIC_QOS_DEFAULT. For further information refer to DataWriterQos. * On create_datawriter() and DataWriter::set_qos() it refers to the default DataWriterQos as returned by get_default_datawriter_qos(). * On set_default_datawriter_qos() it refers to the default constructed DataWriterQos().


When could a sample be removed without being received by the DataReaders?


This could happen in constrained networks or if the publication throughput is too demanding. The callback on_unacknowledged_sample_removed() can be used to detect these situations so the publishing application can apply some solution to ease this issue like reducing the publication rate. For further information refer to on_unacknowledged_sample_removed callback.


19.2.4. SUBSCRIBER

What is the primary consideration when accessing elements on a DDS data sequence after calling "DataReader::read()" or "DataReader::take()" operations?


After calling the DataReader::read() or DataReader::take() operations, accessing the data on the returned sequences is quite easy. The sequences API provides a length() operation returning the number of elements in the collections. The application code just needs to check this value and use the [] operator to access the corresponding elements. Elements on the DDS data sequence should only be accessed when the corresponding element on the SampleInfo sequence indicates that valid data is present. When using Data Sharing, it is also important to check that the sample is valid (i.e. not replaced, refer to DataReader and DataWriter history coupling for further information in this regard. For further information refer to Processing returned data.


What is the primary method for an application to receive new data values from a DataReader without relying on a Listener?


Instead of relying on the Listener to try and get new data values, the application can also dedicate a thread to wait until any new data is available on the DataReader. This can be done using a wait-set to wait for a change on the DataAvailable status. For further information refer to Accessing data with a waiting thread.


How do the "DataReader::read()" and "DataReader::take()" operations (and their variants) return information to the application?


These two operations return information in two sequences: the received DDS data samples are returned in a sequence of the data type and the corresponding information about each DDS sample is returned in a SampleInfo sequence. For further information refer to Loaning and Returning Data and SampleInfo Sequences.


What is the consequence if an application does not return loaned sequences back to the middleware?


If the application does not return the loan by calling the DataReader::return_loan() operation, then Fast DDS will eventually run out of memory to store DDS data samples received from the network for that DataReader. For further information refer to Loaning and Returning Data and SampleInfo Sequences.


What is the purpose of "disposed_generation_count" in relation to an object's lifecycle?


disposed_generation_count indicates the number of times the instance had become alive after it was disposed. For further information refer to disposed_generation_count.


What is the purpose of "no_writers_generation_count" in relation to the instance's lifecycle?


no_writers_generation_count indicates the number of times the instance had become alive after it was disposed as NOT_ALIVE_NO_WRITERS. For further information refer to no_writers_generation_count.



What is the purpose of setting "valid_data" to false in a data sample?


valid_data is a boolean that indicates whether the data sample contains a change in the value or not. Samples with this value set to false are used to communicate a change in the instance status, e.g., a change in the liveliness of the instance. In this case, the data sample should be dismissed as all the relevant information is in the data members of SampleInfo. For further information refer to valid_data.


19.2.5. TOPIC

What is the primary function of a Topic in the context of Publisher-Subscriber communication?


A Topic is a specialization of the broader concept of TopicDescription. A Topic represents a single data flow between Publisher and Subscriber. For further information refer to Topic.


What is the difference between Topics, Keys and Instances?


Topics define the structure of the data being exchanged and are linked to a specific data type. Keys are fields within the data type that uniquely identify different instances of the same Topic. An Instance refers to a specific set of data distinguished by its key values within a Topic, allowing multiple sets of related data (instances) to exist under a single Topic, with updates being directed to the correct instance based on the key. For further information refer to Topics, keys and instances.


How is a Topic created?


Creation of a Topic is done with the create_topic() member function on the DomainParticipant instance, that acts as a factory for the Topic. Mandatory arguments for creating a Topic a string with the name that identifies the topic, the name of the registered data type that will be transmitted and the TopicQos that describes the behavior of the Topic. For further information refer to Creating a Topic.


What type of values can the "like" operator be used with in the context of content Filtered Topic?


The like operator is similar to the one defined by SQL. This operator can only be used with strings. There are two wildcards that could be used in conjunction with this operator. For further information refer to The default SQL-like filter.


What does the "like" operator represent in terms of character matching?


The percent sign %"``(or its alias ``*) represents zero, one, or multiple characters. For further information refer to The default SQL-like filter.


What does the "like" operator's wildcard represent when used in a string comparison?


The underscore sign _ (or its alias ?) represents one single character. For further information refer to The default SQL-like filter.


How is filtering disabled?


If the expression is an empty string, that disables filtering as explained in creating a ContentFilteredTopic. For further information refer to Filtering data on a Topic.


How to enable the usage of a Custom Filter in an application?


To be able to use the Custom Filter in an application, the Custom Filter’s factory must be registered in the DomainParticipant. The next snippet code shows how to register a factory through the API function register_content_filter_factory(). For further information refer to Registering the Factory.


What will happen if an error occurs during the creation of a ContentFilteredTopic using the "create_contentfilteredtopic()" function?


create_contentfilteredtopic() will return a null pointer if there was an error during the operation, e.g., if the related Topic belongs to a different DomainParticipant, a Topic with the same name already exists, syntax errors on the filter expression, or missing parameter values. It is advisable to check that the returned value is a valid pointer. For further information refer to Creating a ContentFilteredTopic using the Custom Filter.


What is the method used to delete a ContentFilteredTopic in the context of a DomainParticipant?


A ContentFilteredTopic can be deleted with the delete_contentfilteredtopic() member function on the DomainParticipant instance where the ContentFilteredTopic was created. For further information refer to Deleting a ContentFilteredTopic.


19.3. RTPS LAYER Frequently Asked Questions

What is the primary function of the RTPS Layer in eprosima Fast DDS, and how does it differ from the DDS Layer?


The lower level RTPS Layer of eprosima Fast DDS serves as an implementation of the protocol defined in the RTPS standard. This layer provides more control over the internals of the communication protocol than the DDS Layer, so advanced users have finer control over the library’s functionalities. For further information, refer to RTPS Layer.


What is the primary responsibility of an "RTPSParticipant" in the context of the RTPS Layer?


As the RTPS standard specifies, RTPSWriters and RTPSReaders are always associated with a History element. In the DDS Layer, its creation and management is hidden, but in the RTPS Layer, you have full control over its creation and configuration. For further information, refer to RTPS Layer.


What is the purpose of creating a "WriterHistory" when creating an RTPS Writer?


Writers are created with RTPSDomain::createRTPSWriter() and configured with a WriterAttributes structure. They also need a WriterHistory which is configured with a HistoryAttributes structure. For further information, refer to RTPS Layer.


What is the purpose of using the "History" element in the RTPS Layer?


In the RTPS Protocol, Readers and Writers save the data about a topic in their associated Histories. Each piece of data is represented by a Change, which eprosima Fast DDS implements as CacheChange_t. Changes are always managed by the History. For further information, refer to RTPS Layer.


How can a custom Payload Pool improve the performance of Writers and Readers in RTPS, and what should be considered when implementing one?


A custom payload pool can improve the performance of writers and readers in RTPS by optimizing memory usage and reducing costly memory allocation operations, especially when dealing with large or variable-sized data. When implementing one, it is essential to ensure that the payload size accommodates the serialized user data plus metadata, and to choose a strategy (e.g., preallocated, dynamic) that balances memory usage and allocation efficiency based on application needs. For further information, refer to Using a custom Payload Pool.


19.4. Discovery Frequently Asked Questions

What are the two main phases involved in the discovery process of Fast DDS?


The two main phases involved in the discovery process of Fast DDS are the Participant Discovery Phase (PDP) and the Endpoint Discovery Phase (EDP). The Participant Discovery Phase (PDP) involves DomainParticipants recognizing each other by sending periodic announcement messages with their unicast addresses. Matching occurs when they are in the same DDS Domain, using multicast by default, though unicast and announcement frequency can be customized. In the Endpoint Discovery Phase (EDP), DataWriters and DataReaders acknowledge each other by sharing information about topics and data types over the established channels. Matching endpoints with the same topic and data type are then ready to exchange user data. For further information, refer to Discovery phases.


What discovery mechanisms does FastDDS provide?


There are four discovery mechanisms in DDS: Simple Discovery, which follows the RTPS standard for both PDP and EDP, ensuring compatibility with other DDS implementations; Static Discovery, which uses the Simple Participant Discovery Protocol (SPDP) but skips the Endpoint Discovery phase if endpoint details are pre-known; Discovery Server, which employs a centralized server for meta traffic discovery; and Manual Discovery, which disables the PDP and requires users to manually match RTPS participants and endpoints using external meta-information channels. For further information, refer to Discovery mechanisms.


How can you improve the chances of successful participant discovery when using the SIMPLE discovery protocol, and what role do initial announcements play in this process?


To improve the chances of successful participant discovery when using the SIMPLE discovery protocol, you can configure initial announcements to send multiple discovery messages at short intervals. This increases the likelihood that DomainParticipants will detect each other despite potential network disruptions or message loss. By adjusting the count (number of announcements) and period (interval between announcements), you can optimize discovery reliability during startup. For further information, refer to SIMPLE Discovery Settings.


What is an initial peer list?


An initial peer list contains one or more IP-port address pairs corresponding to remote DomainParticipants PDP discovery listening resources, so that the local DomainParticipant will not only send its PDP traffic to the default multicast address-port specified by its domain, but also to all the IP-port address pairs specified in the initial peers list. For further information, refer to SIMPLE Discovery Settings.


When could a static configuration of peers be used?


When all DataWriters and DataReaders, and their Topics and data types, are known beforehand, the EDP phase can be replaced with a static configuration of peers. For further information, refer to STATIC Discovery Settings.


What is the primary difference between the Discovery Server mechanism and Simple discovery mechanism in terms of managing metatraffic?


The Discovery Server mechanism is based on a client-server discovery paradigm, the metatraffic is managed by one or several server DomainParticipants, as opposed to simple discovery, where metatraffic is exchanged using a message broadcast mechanism like an IP multicast protocol. For further information, refer to Discovery Server Settings.


What is the primary function of a Discovery Server in the DDS architecture?


The primary function of a Discovery Server in the DDS architecture is to centralize and redistribute discovery information among DomainParticipants, ensuring efficient communication between clients and servers. The server collects discovery data from clients (and other servers) and redistributes it to relevant participants, running a “matching” algorithm to provide only the necessary information for DataWriters and DataReaders to establish communication. It also facilitates server-to-server connections, enabling a more scalable discovery process across the network. For further information, refer to Discovery Server Settings.


What is the primary purpose of a "BACKUP" server in the Discovery Server mechanism?


A BACKUP server is a server that persists its discovery database into a file. This type of server can load the network graph from a file on start-up without the need of receiving any client’s information. For further information, refer to Discovery Server Settings.


What is a client in this context?


A CLIENT is a participant that connects to one or more servers from which it receives only the discovery information they require to establish communication with matching endpoints. For further information, refer to Discovery Server Settings.


What is the difference between a CLIENT and a SUPER_CLIENT?


A SUPER_CLIENT is a client that receives the discovery information known by the server, in opposition to clients, which only receive the information they need. For further information, refer to Discovery Server Settings.


What is the purpose of each server specifying its own locator list in the context of discovery configuration?


Each client must keep a list of locators associated to the servers to which it wants to link. Each server specifies its own locator list which must be populated with RemoteServerAttributes objects with a valid metatrafficUnicastLocatorList or metatrafficMulticastLocatorList. In XML the server list and its elements are simultaneously specified. For further information, refer to Discovery Server Settings.


What is the typical interval of time between discovery messages sent by clients to servers, as described in the text?


As explained above the clients send discovery messages to the servers at regular intervals (ping period) until they receive message reception acknowledgement. The default value for this period is 450 ms. For further information, refer to Discovery Server Settings.


19.5. TRANSPORT LAYER Frequently Asked Questions

19.5.1. Transport API

What is the role of the "TransportDescriptorInterface"?


It acts as a builder for a given transport, allowing to configure the transport and building it, using its create_transport factory member function. For further information, refer to TransportDescriptorInterface.


How is the transport instance created?


Applications do not create the Transport instance themselves. Instead, applications use a TransportDescriptor instance to configure the desired transport, and add this configured instance to the list of user-defined transports of the DomainParticipant. The DomainParticipant will use the factory function on the TransportDescriptor to create the Transport when required. For further information, refer to TransportInterface.


Can I modify the "transport_kind_" data member?


No. transport_kind_ is a protected data member for internal use. It cannot be accessed nor modified from the public API. However, users that are implementing a custom Transport need to fill it with a unique constant value in the new implementation. For further information, refer to TransportInterface.


What is the function of a "Locator_t" in a DDS system?


A Locator_t uniquely identifies a communication channel with a remote peer for a particular transport. For example, on UDP transports, the Locator will contain the information of the IP address and port of the remote peer. The listening Locators, such as Multicast locators (listen to multicast communications), Unicast locators (listen to unicast communications), Metatraffic locators (used to receive metatraffic information, usually used by built-in endpoints to perform discovery), User locators (used by the endpoints created by the user to receive user Topic data changes), are used to receive incoming traffic on the DomainParticipant. For further information, refer to Locator.


What is the primary purpose of the "IPLocator" class?


IPLocator is an auxiliary static class that offers methods to manipulate IP-based locators. It is convenient when setting up a new UDP Transport or TCP Transport, as it simplifies setting IPv4 and IPv6 addresses, or manipulating ports. For further information, refer to Configuring IP locators with IPLocator.


19.5.2. UDP Transport

What is the primary characteristic of UDP transport in terms of communication?


UDP is a connectionless transport, where the receiving DomainParticipant must open a UDP port listening for incoming messages, and the sending DomainParticipant sends messages to this port. For further information, refer to UDP Transport.


What is the best configuration for high-frequency best-effort writers?


Setting non_blocking_send to true. It is also applicable for TCP Transport. For further information, refer to UDPTransportDescriptor.


What is required to enable a new UDP transport in a DomainParticipant?


Fast DDS enables a UDPv4 transport by default. Nevertheless, the application can enable other UDP transports if needed. To enable a new UDP transport in a DomainParticipant, first create an instance of UDPv4TransportDescriptor (for UDPv4) or UDPv6TransportDescriptor (for UDPv6), and add it to the user transport list of the DomainParticipant. For further information, refer to Enabling UDP Transport.


19.5.3. TCP Transport

What is the primary requirement for establishing a connection using TCP transport in DDS?


TCP is a connection-oriented transport, so the DomainParticipant must establish a TCP connection to the remote peer before sending data messages. Therefore, one of the communicating DomainParticipants (the one acting as server) must open a TCP port listening for incoming connections, and the other one (the one acting as client) must connect to this port. For further information, refer to TCP Transport.


What happens if there are multiple listening ports in TCP transport?


Only the first listening port will be effectively used. The rest of the ports will be ignored. For further information, refer to TCPTransportDescriptor.


What happens if "listening_ports" is left empty?


If listening_ports is left empty, the participant will not be able to receive incoming connections but will be able to connect to other participants that have configured their listening ports. For further information, refer to TCPTransportDescriptor.


How is TCP transport enabled?


There are several ways of enabling TCP transport in Fast-DDS. The first option is to modify the builtin transports that are responsible for the creation of the DomainParticipant transports. The second option is to set up a Server-Client configuration. You need to create an instance of TCPv4TransportDescriptor (for TCPv4) or TCPv6TransportDescriptor (for TCPv6), and add it to the user transport list of the DomainParticipant. For further information, refer to Enabling TCP Transport.


What configuration is required on the server side to enable communication with the client over TCP?


The router must be configured to forward traffic incoming to port 5100. For further information, refer to TCPTransportDescriptor.


Which configuration is needed to allow incoming connections through a WAN?


The TCPv4TransportDescriptor must indicate its public IP address in the wan_addr data member. On the client side, the DomainParticipant must be configured with the public IP address and listening_ports of the TCP as Initial peers. For further information, refer to WAN or Internet Communication over TCPv4.


Is there any configuration that makes the TCP transport more secure?


Yes, with TLS by including apply_security=true data member and tls_config data member on the TCPTransportDescriptor. For further information, refer to TLS over TCP.


What are the advantages and disadvantages of using TCP transport compared to UDP transport?


TCP offers reliable data transmission with built-in mechanisms for error detection, correction, and ordered delivery of packets, ensuring data integrity and sequencing. It also includes flow control to adjust the transmission rate between sender and receiver. However, this reliability comes with increased overhead, resulting in slower transmission speeds and higher latency compared to UDP. UDP, on the other hand, is faster with lower latency, as it does not ensure packet delivery, order, or perform error correction, making it ideal for real-time applications like video streaming or gaming, but less reliable for applications requiring data accuracy.


19.5.4. Shared Memory Transport

What is the primary advantage of using the Shared Memory Transport (SHM) compared to other network transports like UDP/TCP?


The shared memory (SHM) transport enables fast communications between entities running in the same processing unit/machine, relying on the shared memory mechanisms provided by the host operating system. For further information, refer to Shared Memory Transport.


How are peers running in the same host identified?


Using the DomainParticipant’s GuidPrefix_t. Two participants with identical 4 first bytes on the GuidPrefix_t are considered to be running in the same host. For further information, refer to Shared Memory Transport.


What is a Segment Buffer in the context of the Shared Memory Transport?


A buffer allocated in the shared memory Segment. It works as a container for a DDS message that is placed in the Segment. In other words, each message that the DomainParticipant writes on the Segment will be placed in a different buffer. For further information, refer to Segment Buffer.


What is a Buffer Descriptor?


It acts as a pointer to a specific Segment Buffer in a specific Segment. It contains the segmentId and the offset of the Segment Buffer from the base of the Segment. When communicating a message to other DomainParticipants, Shared Memory Transport only distributes the Buffer Descriptor, avoiding the copy of the message from a DomainParticipant to another. With this descriptor, the receiving DomainParticipant can access the message written in the buffer, as is uniquely identifies the Segment (through the segmentId) and the Segment Buffer (through its offset). For further information, refer to Buffer Descriptor.


What is the primary purpose of creating a listener for a DomainParticipant's receiving port in the context of Shared Memory Transport?


DomainParticipants create a listener to their receiving port, so that they can be notified when a new Buffer Descriptor is pushed to the port. For further information, refer to Port.


What is the purpose of performing a health check when a DomainParticipant opens a Port?


Every time a DomainParticipant opens a Port (for reading or writing), a health check is performed to assess its correctness. The reason is that if one of the processes involved crashes while using a Port, that port can be left inoperative. If the attached listeners do not respond in a given timeout, the Port is considered damaged, and it is destroyed and created again. For further information, refer to Port Health Check.


How is SHM transport enabled?


Fast DDS enables a SHM transport by default. Nevertheless, the application can enable other SHM transports if needed. To enable a new SHM transport in a DomainParticipant, first create an instance of SharedMemTransportDescriptor, and add it to the user transport list of the DomainParticipant. For further information, refer to Enabling Shared Memory Transport.


What happens to discovery traffic when multiple transports are enabled in a DomainParticipant?


The discovery traffic is always performed using the UDP/TCP transport, even if the SHM transport is enabled in both participants running in the same machine. For further information, refer to Enabling Shared Memory Transport.


19.5.5. Data Sharing Delivery

What is the difference between Data Sharing Delivery and Shared Memory Transport?


Although Data-sharing delivery uses shared memory, it differs from Shared Memory Transport in that Shared Memory is a full-compliant transport. That means that with Shared Memory Transport the data being transmitted must be copied from the DataWriter history to the transport and from the transport to the DataReader. With Data-sharing these copies can be avoided. For further information, refer to Data-sharing delivery.


Does the use of Data-sharing avoid data copies between the application and the DataReader and DataWriter?


No, it does not prevent data copies. Data-sharing helps avoid copies between the DataWriter and DataReader by using shared memory for communication, but data still needs to be copied between the application and the DataWriter or DataReader. To avoid these copies, a different mechanism, such as Zero-Copy communication, is required. For further information, refer to Data-sharing delivery.


How are data copies prevented?


Data copies can be prevented in some cases using Zero-Copy communication. For further information, refer to Data-sharing delivery.


What is required for two entities to use data-sharing delivery between them, according to their DataSharingQosPolicy configuration?


Two entities will be able to use data-sharing delivery between them only if both have at least a common domain. For further information, refer to Data-sharing delivery.


What is the default value for the maximum number of Data-sharing domain identifiers, and what does it affect?


By default, there is no limit to the number of identifiers. The default value can be changed using the max_domains() function. For further information, refer to Data-sharing delivery.


What is the consequence of the DataWriter reusing a sample from the pool to publish new data?


The DataReader loses access to the old data sample. For further information, refer to DataReader and DataWriter history coupling.


Can the communications between entities be sped up?


Yes, but only within the same process using intra-process delivery. For further information, refer to Intra-process delivery.


How are peers running in the same process identified?


Fast DDS utilizes the DomainParticipant’s GuidPrefix_t to identify peers running in the same process. Two participants with identical 8 first bytes on the GuidPrefix_t are considered to be running in the same process. For further information, refer to GUID Prefix considerations for intra-process delivery.


19.6. PERSISTENCE SERVICE Frequently Asked Questions

What is persistence in eProsima Fast DDS?


Persistence is a mechanism that allows recovering a previous state on starting the DDS. This is done by configuring the DataWriter’s history to be stored in a persistent database, so that the DataWriter can load its history from it on creation. Furthermore, DataReaders can be configured to store the last notified change in the database, so that they can recover their state on creation. For more information, refer to Persistence Service.


Why is it useful?


It adds robustness to applications in case of unexpected shutdowns. For further information, refer to Persistence Service.


How is the persistence database managed?


A persistence plugin must be configured for managing the database using the property dds.persistence.plugin. For more information, refer to Configuration.


What type of database does the persistence plugin use?


It uses SQLite3 API. For more information, refer to PERSISTENCE:SQLITE3 built-in plugin.


19.7. Security Frequently Asked Questions

What security plugins does Fast DDS offer for secure communication?


Fast DDS offers five built-in security plugins as part of the DDS Security specification: the Authentication plugin (Authentication plugin: DDS:Auth:PKI-DH) provides authentication between DomainParticipants using a trusted Certificate Authority (CA) and mutual authentication; the Access Control plugin (Access control plugin: DDS:Access:Permissions) enforces permissions for protected operations; the Cryptographic plugin (Cryptographic plugin: DDS:Crypto:AES-GCM-GMAC) ensures authenticated encryption and data integrity using AES in Galois Counter Mode (AES-GCM); the Logging plugin (Logging plugin: DDS:Logging:DDS_LogTopic) logs security-related events. For further information, refer to Security.


Is the security support configured by default?


No. It must be activated using -DSECURITY=ON at the CMake configuration step. For further information, refer to Security.


19.7.1. Authentication

What is the purpose of authentication?


When a DomainParticipant is either locally created or discovered, it needs to be authenticated in order to be able to communicate in a DDS Domain. For further information, refer to Authentication plugin: DDS:Auth:PKI-DH.


What happens if the authentication fails?


The remote DomainParticipant is rejected, therefore communication cannot take place in the DDS Domain for this DomainParticipant. For further information, refer to Authentication plugin: DDS:Auth:PKI-DH.


How is the DDS:Auth:PKI-DH authentication plugin activated?


By setting the properties() dds.sec.auth.plugin with the value`` builtin.PKI-DH. For further information, refer to Authentication plugin: DDS:Auth:PKI-DH.


What is the process for generating and managing security certificates for the Authentication plugin?


The process for generating and managing security certificates for the Authentication plugin involves creating and managing X.509 certificates. First, since multiple certificates will need to be issued, one for each of the DomainParticipants, a dedicated CA is set up, and the CA’s certificate is installed as the root key of all DomainParticipants. Thus, the DomainParticipants will accept all certificates issued by our own CA. To create a proprietary CA certificate, a configuration file must first be written with the CA information. After writing the configuration file, the certificate is generates using the Elliptic Curve Digital Signature Algorithm (ECDSA). As was done for the CA, a DomainParticipant certificate configuration file needs to be created first. After writing the DomainParticipant certificate configuration file, the X.509 certificate is generated using ECDSA, for a DomainParticipant. Finally, the CRL is created. This is a list of the X.509 certificates revoked by the certificate issuing CA before they reach their expiration date. Any certificate that is on this list will no longer be trusted. For further information, refer to Generation of X.509 certificates.


19.7.2. Access control

What is the purpose of access control?


Provides the mechanisms and operations required to validate the DomainParticipant permissions and define access rights over a resource. For further information, refer to Access control plugin: DDS:Access:Permissions.


How is the DDS:Access:Permissions authentication plugin activated?


By setting the properties() dds.sec.access.plugin with the value builtin.Access-Permissions. For further information, refer to Access control plugin: DDS:Access:Permissions.


Can a DomainParticipant match with a remote DomainParticipant without authentication?


Yes. This can be delimited by the <allow_unauthenticated_participants> XML element tag. When it is set to true, the DomainParticipant can match other DomainParticipants without authentication. For further information, refer to Allow Unauthenticated Participants.


Can the secure channel of the endpoint discovery phase be encrypted?


Yes, if the <discovery_protection_kind> XML element is set to ENCRYPT. This is also applicable for Liveliness and RTPS. For further information, refer to Access control plugin: DDS:Access:Permissions.


How is the access to topics managed?


By applying topic rules to any DataReader or DataWriter associated with a topic that matches the Topic expression name. For further information, refer to Topic Rule.


What is the purpose of a DomainParticipant Permissions Document in the DDS:Auth:PKI-DH plugin?


The permissions document is an XML file that contains the permissions of a DomainParticipant and binds them to the DomainParticipant distinguished name defined in the DDS:Auth:PKI-DH plugin. For further information, refer to DomainParticipant Permissions Document.


What are the main components of a DomainParticipant Permissions document in DDS?


There are several sections. Grant Section, delimited by the <grant> XML element tag, including the subject name, validity, and rules. Domains sections, delimited by the XML element <domains>, identifying the collection of DDS Domains to which the rule applies. Allowed/Denied Actions sections for publishing, subscribing, relaying, topics, and partitions. For further information, refer to DomainParticipant Permissions Document.


19.7.3. Data encryption

What is the function of the cryptographic plugin in the context of DDS?


The cryptographic plugin provides the tools and operations required to support encryption and decryption, digests computation, message authentication codes computation and verification, key generation, and key exchange for DomainParticipants, DataWriters, and DataReaders. For further information, refer to Cryptographic plugin: DDS:Crypto:AES-GCM-GMAC.


How is the DDS:Crypto:AES-GCM-GMAC authentication plugin activated?


By setting the properties() dds.sec.crypto.plugin with the value builtin.AES-GCM-GMAC. Moreover, this plugin needs the activation of the Authentication plugin: DDS:Auth:PKI-DH and the DDS:Access:Permissions. For further information, refer to Cryptographic plugin: DDS:Crypto:AES-GCM-GMAC.


19.7.4. Logging

What is the function of the logging plugin in Fast DDS?


The logging plugin provides the necessary operations to log the security events triggered by the other security plugins supported by Fast DDS. For further information, refer to Logging plugin: DDS:Logging:DDS_LogTopic.


How is the DDS:Logging:DDS_LogTopic authentication plugin activated?


By setting the properties() dds.sec.log.plugin with the value builtin.DDS_LogTopic. For further information, refer to Logging plugin: DDS:Logging:DDS_LogTopic.


19.8. Logging Frequently Asked Questions

What are the functionalities of the logging module?


There are three functionalities in the logging module: three logging levels, for info, warnings and errors; message filtering; and output to STDOUT, STDERR and log files. For further information, refer to Logging.


What are the main classes in the logging module?


The Log class is in charge of the logging operations and provides configuration APIs to set different logging configuration aspects and logging filtering at various levels. The LogConsumer class includes the member functions that derived classes should overload to consume log entries. For further information, refer to Module Structure.


How does the logging module prevent blocking of the application thread when a logging operation is performed?


When it is created, the logging module creates a thread that awakens every time an entry is added to the queue and falls back into idle state once the work is done. For further information, refer to Logging Thread.


How is the logging of messages handled?


It is handled by three macros, for log messages with Log::Kind::Info, Log::Kind::Warning, and Log::Kind::Info verbosities. These macros produce a log entry showing a message and some meta information. For further information, refer to Logging Messages.


What is the purpose of assigning a category to log entries in the logging module?


The category component can be used to filter log entries so that only those categories specified in the filter are consumed. For further information, refer to Category.


What are the three different filtering possibilities provided by the *eProsima Fast DDS* logging module for log entry filtering?


Fast DDS provides three different filtering possibilities: Category Filtering, File Name Filtering, Content Filtering. For further information, refer to Filters.


What is the order in which log entry filters are applied when consuming logs in *eProsima Fast DDS*?


Filters are applied in the specific order presented in the previous question, meaning that file name filtering is only applied to the entries that pattern-match the category filter, and content filtering is only applied to the entries that pattern-match both category and file name filters. For further information, refer to Filters.


What is the primary method for filtering log entries by their Category component in the *eProsima Fast DDS* logging module?


Log entries can be filtered upon consumption according to their Category component using regular expressions. Each time an entry is ready to be consumed, the category filter is applied using std::regex_search(). To set a category filter, the member function Log::SetCategoryFilter() is used. For further information, refer to Category Filtering.


What is the purpose of setting a file name filter in the context of log entry consumption?


Log entries can be filtered upon consumption according to their File Context component using regular expressions. Each time an entry is ready to be consumed, the file name filter is applied using std::regex_search(). To set a file name filter, the member function Log::SetFilenameFilter() is used. For further information, refer to File Name Filtering.


What is the method for filtering log entries in terms of their message component?


Log entries can be filtered upon consumption according to their Message component using regular expressions. Each time an entry is ready to be consumed, the content filter is applied using std::regex_search(). To set a content filter, the member function Log::SetErrorStringFilter() is used. For further information, refer to Content Filtering.


What are consumers?


Consumers are classes that take a Log::Entry and produce a log output accordingly. For further information, refer to Consumers.


What is the function of a "StdoutErrConsumer" in the context of log output?


StdoutErrConsumer: Outputs log entries to STDOUT or STDERR depending on the given threshold. For further information, refer to Consumers.


What is the primary function of the "FileConsumer" class in the context of logging?


FileConsumer: Outputs log entries to a user specified file. For further information, refer to FileConsumer.


What is the primary function of the "StdoutConsumer" class, as described in the provided text?


StdoutConsumer outputs log entries to the STDOUT stream following the convention specified in the Log Entry Specification . It is the default logging module if the CMake option LOG_CONSUMER_DEFAULT is set to STDOUT.


19.9. XML PROFILES Frequently Asked Questions

How are XML profiles defined?


The XML profiles are defined within the <dds> element, and in turn, within the <profiles> XML elements. For further information, refer to Creating an XML profiles file.


What happens if an XML file is loaded multiple times?


If the same XML profile file is loaded multiple times, the second loading of the file will result in an error together with the consequent error log. For further information, refer to Loading and applying profiles.


What is stand-alone profiles definition?


The element defining the XML profile is the root element of the XML file. For further information, refer to Rooted vs Standalone profiles definition.


What is rooted profile definition?


The element defining the XML profile is the child element of another element. For further information, refer to Rooted vs Standalone profiles definition.


What do DomainParticipant profiles do?


The DomainParticipant profiles allow the definition of the configuration of DomainParticipants through XML files. These profiles are defined within the <participant> XML tags. For further information, refer to DomainParticipant profiles.


What are the domain participant XML attributes?


The <participant> element has two attributes defined: profile_name and is_default_profile. For further information, refer to DomainParticipant XML attributes.


How is the DomainParticipant configured?


The <participant> element has two child elements: <domainId> and <rtps> . All the DomainParticipant configuration options belong to the <rtps> element, except for the DDS DomainId which is defined by the <domainId> element. For further information, refer to DomainParticipant configuration.


What do DataWriter profiles do?


The DataWriter profiles allow for configuring DataWriters from an XML file. These profiles are defined within the <data_writer> XML tags. For further information, refer to DataWriter profiles.


What are the XML attributes of the DataWriter?


The <data_writer> element has two attributes defined: profile_name and is_default_profile. For further information, refer to DataWriter profiles.


What do DataReader profiles do?


The DataReader profiles allow declaring DataReaders from an XML file. These profiles are defined within the <data_reader> XML tags. For further information, refer to DataReader profiles.


What are the XML attributes of the DataReader?


The <data_reader> element has two attributes defined: profile_name and is_default_profile. For further information, refer to DataReader profiles.


What do Topic profiles do?


The <topic> element has two attributes defined: profile_name and is_default_profile. For further information, refer to Topic profiles.


What are the available XML elements for configuring transport layer parameters in Fast DDS, and what is their purpose?


This section defines the XML elements available for configuring the transport layer parameters in Fast DDS. These elements are defined within the XML tag <transports_descriptors>. The <transport_descriptors> can contain one or more <transport_descriptor> XML elements. Each <transport_descriptor> element defines a configuration for a specific type of transport protocol. For further information, refer to Transport descriptors.


Are log profiles available?


eProsima Fast DDS allows for registering and configuring Log consumers using XML configuration files. The logging profiles are defined within the <log> XML tags. The <log> element has two child elements: <use_default> and <consumer>. For further information, refer to Log profiles.


What is the advantage of having Dynamic Language Binding support in XML files?


The topic data types can be modified without the need to modify the source code of the DDS application. For further information, refer to Dynamic Types profiles.


How are Dynamic Types configured with XML?


Dynamic Types in Fast DDS are configured using XML files, where data types are defined within <types> elements. Each <types> element can contain one or more <type> definitions. Members of these types, such as primitive or complex types like structures, unions, sequences, arrays, and maps, are specified using the <member> tag along with appropriate attributes for the type and its characteristics. Once the XML file is created, it can be loaded into the Fast DDS application using the load_XML_profiles_file() function, allowing the types to be dynamically used without modifying the application’s source code. For further information, refer to Dynamic Types profiles.


19.10. Environment Variables Frequently Asked Questions

What are the most important environment variables that affect the behavior of Fast DDS?


FASTDDS_DEFAULT_PROFILES_FILE, SKIP_DEFAULT_XML, FASTDDS_BUILTIN_TRANSPORTS, ROS_DISCOVERY_SERVER, ROS_SUPER_CLIENT, FASTDDS_STATISTICS, FASTDDS_ENVIRONMENT_FILE. For further information, refer to Environment variables.


What is the purpose of the "FASTDDS_DEFAULT_PROFILES_FILE" environment variable?


Defines the location of the default profile configuration XML file. For further information, refer to FASTDDS_DEFAULT_PROFILES_FILE.


What happens when the variable "SKIP_DEFAULT_XML" is set to 1?


Skips looking for a default profile configuration XML file. If this variable is set to 1, Fast DDS will load the configuration parameters directly from the classes’ definitions without looking for the DEFAULT_FASTDDS_PROFILES.xml in the working directory. For further information, refer to SKIP_DEFAULT_XML.


What is the primary purpose of the "FASTDDS_BUILTIN_TRANSPORTS" environment variable?


Setting this variable allows to modify the builtin transports that are initialized during the DomainParticipant creation. For further information, refer to FASTDDS_BUILTIN_TRANSPORTS.


What is the purpose of the "ROS_DISCOVERY_SERVER" environment variable?


Setting this variable configures the DomainParticipant to connect to one or more servers using the Discovery Server discovery mechanism. For further information, refer to ROS_DISCOVERY_SERVER.


What happens to a "DomainParticipant" when its discovery protocol is set to "SIMPLE" and "ROS_SUPER_CLIENT" is set to TRUE?


If the DomainParticipant’s discovery protocol is set to SIMPLE, and ROS_SUPER_CLIENT is set to TRUE, the participant is automatically promoted to a SUPER_CLIENT. For further information, refer to ROS_SUPER_CLIENT.


What is the purpose of setting the "FASTDDS_STATISTICS" environment variable, according to the provided information?


Setting this variable configures the DomainParticipant to enable the statistics DataWriters which topics are contained in the list set in this environment variable. For further information, refer to FASTDDS_STATISTICS.


What happens when you set the "FASTDDS_ENVIRONMENT_FILE" environment variable to a JSON file?


Setting this environment variable to an existing json file allows to load the environment variables from the file instead of from the environment. For further information, refer to FASTDDS_ENVIRONMENT_FILE.


19.11. Statistics Module Frequently Asked Questions

What is the purpose of the statistics module?


The Fast DDS Statistics module is an extension of Fast DDS that enables the recollection of data concerning the DDS communication. For further information, refer to Statistics Module.


How does the statistics module work?


The collected data is published using DDS over dedicated topics using builtin DataWriters within the Statistics module. For further information, refer to Statistics Domain Participant.


What is the consequence of compiling the statistics module?


It may entail affecting the application’s performance. For further information, refer to Statistics Module.


How can we activate the statistics module?


It can be activated using the -DFASTDDS_STATISTICS=ON at CMake configuration step. For further information, refer to Statistics Module.


How can we start collecting data?


In order to start collecting data in one of the statistics topics, the corresponding statistics DataWriter should be enabled. For further information, refer to Statistics Domain Participant.


How can we enable the statistics DataWriter?


It can either be done automatically or be enabled at run time using one of two methods: enable_statistics_datawriter() or enable_statistics_datawriter_with_profile(). For further information, refer to Enable statistics DataWriters.


How is the environment variable "FASTDDS_STATISTICS" used?


The environment variable is only used in the case where the CMake option FASTDDS_STATISTICS has been enabled. In any other case, the environment variable has no effect. The statistics DataWriters that will be enabled when the DomainParticipant is enabled would be the union between those specified in the properties() fastdds.statistics and those included with the environment variable. For further information, refer to FASTDDS_STATISTICS.


What is the monitor service?


The Monitor Service targets any application implementing the subscription side of the Monitor Service Status Topic, giving the possibility of retrieving the Monitoring Information of the local entities. For further information, refer to Introduction.


What Information can the monitor service carry?


It can carry information about the monitoring information of the local entities of a particular DomainParticipant. For further information, refer to Introduction.


How can the monitor service be activated?


The Monitor Service can be activated using the -DFASTDDS_STATISTICS=ON at CMake configuration step. For further information, refer to Monitor Service Configuration.


At which layers can the monitor service be enabled?


It can be programmatically enabled in both DDS Layer and RTPS Layer through the enable_monitor_service() and disable_monitor_service() calls. For further information, refer to Monitor Service Configuration.


19.12. XTypes Frequently Asked Questions

What are XTypes?


Extensible and Dynamic Topic Types for DDS specification. This specification defines the following concepts: DDS supported type system; type representation, including IDL and TypeObject representation representations; data representation over the wire; language binding; DDS builtin mechanism to automatically discover remote data types. For more information, refer to XTypes


How does the remote data type discovery mechanism work?


The remote data type discovery mechanism is based on the exchange of the data type information optimized in order to reduce the required bandwidth. For more information, refer to Remote Data Types Discovery.


What prerequisites are required for the remote data type discovery feature to work?


The local data types must be registered into the ITypeObjectRegistry. TypeInformation should be received with the DomainParticipant’s endpoint discovery information. A DomainParticipant that does not inform about its TypeInformation would not trigger the remote data type discovery mechanism. For more information, refer to Remote Data Types Discovery.


What is the purpose of the Dynamic Language Binding API?


The Dynamic Language Binding API allows to define data types at runtime instead of having the types predefined as it is required by the Plain Language Binding. For further information, refer to Dynamic Language Binding.


How can complex data types be managed?


Dynamic Language Binding provides two possible approaches for managing complex data types: DynamicData::get_complex_value and DynamicData::set_complex_value; DynamicData::loan_value, which allows to loan a reference to a DynamicData to work with preventing the data copy. For further information, refer to Dynamic Language Binding.


What is serialization?


Serialization is a crucial process in data distribution services, as it converts complex data structures into a format that can be easily transmitted and reconstructed across different platforms and programming environments. For further information, refer to Serialization Utilities.


What are the formats supported for the serialization?


A Dynamic Type can be serialized to its IDL representation and to JSON (primitives, strings, enumerations, bitmasks, sequences, arrays, maps, structures, unions, bitsets). For further information, refer to Serialization Utilities.


20. C++ API Reference

Fast DDS, as a Data Distribution Service (DDS) standard implementation, exposes the DDS Data-Centric Publish-Subscribe (DCPS) Platform Independent Model (PIM) API, as specified in the DDS specification. Furthermore, is also gives the user the possibility to directly interact with the underlying Real-time Publish-Subscribe (RTPS) API that DDS implements for wired communications, as specified in the RTPS standard.

This section presents the most commonly used APIs provided by Fast DDS. For more information about the API reference, please refer to Fast DDS API reference.

20.1. DDS DCPS PIM

Data Distribution Service (DDS) Data-Centric Publish-Subscribe (DCPS) Platform Independent Model (PIM) API

20.1.1. Core

20.1.1.1. Condition
20.1.1.1.1. Condition
class Condition

The Condition class is the root base class for all the conditions that may be attached to a WaitSet.

Subclassed by eprosima::fastdds::dds::GuardCondition, eprosima::fastdds::dds::ReadCondition, eprosima::fastdds::dds::StatusCondition

Public Functions

inline virtual bool get_trigger_value() const

Retrieves the trigger_value of the Condition.

Returns:

true if trigger_value is set to ‘true’, ‘false’ otherwise

20.1.1.1.2. ConditionSeq
using eprosima::fastdds::dds::ConditionSeq = std::vector<Condition*>
20.1.1.1.3. GuardCondition
class GuardCondition : public eprosima::fastdds::dds::Condition

The GuardCondition class is a specific Condition whose trigger_value is completely under the control of the application.

The purpose of the GuardCondition is to provide the means for the application to manually wakeup a WaitSet. This is accomplished by attaching the GuardCondition to the WaitSet and then setting the trigger_value by means of the set_trigger_value operation.

Public Functions

virtual bool get_trigger_value() const override

Retrieves the trigger_value of the Condition.

Returns:

true if trigger_value is set to ‘true’, ‘false’ otherwise

ReturnCode_t set_trigger_value(bool value)

Set the trigger_value.

Parameters:

value – new value for trigger

Returns:

RETURN_OK

20.1.1.1.4. StatusCondition
class StatusCondition : public eprosima::fastdds::dds::Condition

The StatusCondition class is a specific Condition that is associated with each Entity.

Public Functions

virtual bool get_trigger_value() const override

Retrieves the trigger_value of the Condition.

Returns:

true if trigger_value is set to ‘true’, ‘false’ otherwise

ReturnCode_t set_enabled_statuses(const StatusMask &mask)

Defines the list of communication statuses that are taken into account to determine the trigger_value.

Parameters:

mask – defines the mask for the status

Returns:

RETCODE_OK with everything ok, error code otherwise

const StatusMask &get_enabled_statuses() const

Retrieves the list of communication statuses that are taken into account to determine the trigger_value.

Returns:

Status set or default status if it has not been set

Entity *get_entity() const

Returns the Entity associated.

Returns:

Entity

20.1.1.1.5. Wait-set
class WaitSet

The WaitSet class allows an application to wait until one or more of the attached Condition objects has a trigger_value of TRUE or until timeout expires.

Public Functions

ReturnCode_t attach_condition(const Condition &cond)

Attaches a Condition to the Wait Set.

Parameters:

condCondition

Returns:

RETCODE_OK if attached correctly, error code otherwise

ReturnCode_t detach_condition(const Condition &cond)

Detaches a Condition from the WaitSet.

Parameters:

condCondition

Returns:

RETCODE_OK if detached correctly, PRECONDITION_NOT_MET if condition was not attached

ReturnCode_t wait(ConditionSeq &active_conditions, const dds::Duration_t timeout) const

Allows an application thread to wait for the occurrence of certain conditions. If none of the conditions attached to the WaitSet have a trigger_value of true, the wait operation will block suspending the calling thread.

Parameters:
  • active_conditions – Reference to the collection of conditions which trigger_value are true

  • timeout – Maximum time of the wait

Returns:

RETCODE_OK if everything correct, PRECONDITION_NOT_MET if WaitSet already waiting, TIMEOUT if maximum time expired, error code otherwise

ReturnCode_t get_conditions(ConditionSeq &attached_conditions) const

Retrieves the list of attached conditions.

Parameters:

attached_conditions – Reference to the collection of attached conditions

Returns:

RETCODE_OK if everything correct, error code otherwise

20.1.1.2. DomainEntity
class DomainEntity : public eprosima::fastdds::dds::Entity

The DomainEntity class is a subclass of Entity created in order to differentiate between DomainParticipants and the rest of Entities.

Subclassed by eprosima::fastdds::dds::DataReader, eprosima::fastdds::dds::DataWriter, eprosima::fastdds::dds::Publisher, eprosima::fastdds::dds::Subscriber, eprosima::fastdds::dds::Topic

Public Functions

inline DomainEntity(const StatusMask &mask = StatusMask::all())

Constructor.

Parameters:

maskStatusMask (default: all)

20.1.1.3. Entity
class Entity

The Entity class is the abstract base class for all the objects that support QoS policies, a listener and a status condition.

Subclassed by eprosima::fastdds::dds::DomainEntity, eprosima::fastdds::dds::DomainParticipant

Public Functions

inline Entity(const StatusMask &mask = StatusMask::all())

Constructor.

Parameters:

maskStatusMask (default: all)

inline virtual ReturnCode_t enable()

This operation enables the Entity.

Returns:

RETCODE_OK

inline void close()

This operation disables the Entity before closing it.

inline const StatusMask &get_status_mask() const

Retrieves the set of relevant statuses for the Entity.

Returns:

Reference to the StatusMask with the relevant statuses set to 1

const StatusMask &get_status_changes() const

Retrieves the set of triggered statuses in the Entity.

Triggered statuses are the ones whose value has changed since the last time the application read the status. When the entity is first created or if the entity is not enabled, all communication statuses are in the non-triggered state, so the list returned by the get_status_changes operation will be empty. The list of statuses returned by the get_status_changes operation refers to the status that are triggered on the Entity itself and does not include statuses that apply to contained entities.

Returns:

const reference to the StatusMask with the triggered statuses set to 1

inline const InstanceHandle_t &get_instance_handle() const

Retrieves the instance handler that represents the Entity.

Returns:

Reference to the InstanceHandle

inline bool is_enabled() const

Checks if the Entity is enabled.

Returns:

true if enabled, false if not

inline StatusCondition &get_statuscondition()

Allows access to the StatusCondition associated with the Entity.

Returns:

Reference to StatusCondition object

inline const StatusCondition &get_statuscondition() const

Allows access to the StatusCondition associated with the Entity.

Returns:

Const Reference to StatusCondition object

20.1.1.4. LoanableArray
template<typename T, std::size_t num_items>
struct LoanableArray : public std::array<T, num_items>

A type-safe, ordered collection of elements allocated on the stack, which can be loaned to a LoanableCollection.

Public Functions

inline void **buffer_for_loans() const

Get a buffer pointer that could be used on LoanableCollection::loan.

Returns:

buffer pointer for loans.

20.1.1.5. LoanableCollection
class LoanableCollection

A collection of generic opaque pointers that can receive the buffer from outside (loan).

This is an abstract class. See LoanableSequence for details.

Subclassed by eprosima::fastdds::dds::LoanableTypedCollection< T, _NonConstEnabler >, eprosima::fastdds::dds::UserAllocatedSequence, eprosima::fastdds::dds::LoanableTypedCollection< T >, eprosima::fastdds::dds::LoanableTypedCollection< T, std::true_type >

Public Functions

inline const element_type *buffer() const

Get the pointer to the elements buffer.

The returned value may be nullptr if maximum() is 0. Otherwise it is guaranteed that up to maximum() elements can be accessed.

Returns:

the pointer to the elements buffer.

inline bool has_ownership() const

Get the ownership flag.

Returns:

whether the collection has ownership of the buffer.

inline size_type maximum() const

Get the maximum number of elements currently allocated.

Returns:

the maximum number of elements currently allocated.

inline size_type length() const

Get the number of elements currently accessible.

Returns:

the number of elements currently accessible.

inline bool length(size_type new_length)

Set the number of elements currently accessible.

This method tells the collection that a certain number of elements should be accessible. If the new length is greater than the current maximum() the collection should allocate space for the new elements. If this is the case and the collection does not own the buffer (i.e. has_ownership() is false) then no allocation will be performed, the length will remain unchanged, and false will be returned.

Parameters:

new_length[in] New number of elements to be accessible.

Pre:

new_length >= 0

Returns:

true if the new length was correctly set.

Post:

length() == new_length

Post:

maximum() >= new_length

inline bool loan(element_type *buffer, size_type new_maximum, size_type new_length)

Loan a buffer to the collection.

Parameters:
  • buffer[in] pointer to the buffer to be loaned.

  • new_maximum[in] number of allocated elements in buffer.

  • new_length[in] number of accessible elements in buffer.

Pre:

(has_ownership() == false) || (maximum() == 0)

Pre:

new_maximum > 0

Pre:

new_maximum >= new_length

Pre:

buffer != nullptr

Returns:

false if preconditions are not met.

Returns:

true if operation succeeds.

Post:

buffer() == buffer

Post:

has_ownership() == false

Post:

maximum() == new_maximum

Post:

length() == new_length

inline element_type *unloan(size_type &maximum, size_type &length)

Remove the loan from the collection.

Parameters:
  • maximum[out] number of allocated elements on the returned buffer.

  • length[out] number of accessible elements on the returned buffer.

Pre:

has_ownership() == false

Returns:

nullptr if preconditions are not met.

Returns:

pointer to the previously loaned buffer of elements.

Post:

buffer() == nullptr

Post:

has_ownership() == true

Post:

length() == 0

Post:

maximum() == 0

inline element_type *unloan()

Remove the loan from the collection.

Pre:

has_ownership() == false

Returns:

nullptr if preconditions are not met.

Returns:

pointer to the previously loaned buffer of elements.

Post:

buffer() == nullptr

Post:

has_ownership() == true

Post:

length() == 0

Post:

maximum() == 0

20.1.1.6. LoanableSequence
template<typename T, typename _NonConstEnabler = std::true_type>
class LoanableSequence : public eprosima::fastdds::dds::LoanableTypedCollection<T, std::true_type>

A type-safe, ordered collection of elements that can receive the buffer from outside (loan).

For users who define data types in OMG IDL, this type corresponds to the IDL express sequence<T>.

For any user-data type Foo that an application defines for the purpose of data-distribution with Fast DDS, a ‘using FooSeq = LoanableSequence<Foo>’ is generated. The sequence offers a subset of the methods defined by the standard OMG IDL to C++ mapping for sequences. We refer to an IDL ‘sequence<Foo>’ as FooSeq.

The state of a sequence is described by the properties ‘maximum’, ‘length’ and ‘has_ownership’.

  • The ‘maximum’ represents the size of the underlying buffer; this is the maximum number of elements it can possibly hold. It is returned by the maximum() operation.

  • The ‘length’ represents the actual number of elements it currently holds. It is returned by the length() operation.

  • The ‘has_ownership’ flag represents whether the sequence owns the underlying buffer. It is returned by the has_ownership() operation. If the sequence does not own the underlying buffer, the underlying buffer is loaned from somewhere else. This flag influences the lifecycle of the sequence and what operations are allowed on it. The general guidelines are provided below and more details are described in detail as pre-conditions and post-conditions of each of the sequence’s operations:

  • If has_ownership == true, the sequence has ownership on the buffer. It is then responsible for destroying the buffer when the sequence is destroyed.

  • If has_ownership == false, the sequence does not have ownership on the buffer. This implies that the sequence is loaning the buffer. The sequence should not be destroyed until the loan is returned.

  • A sequence with a zero maximum always has has_ownership == true

Public Functions

LoanableSequence() = default

Default constructor.

Creates the sequence with no data.

Post:

buffer() == nullptr

Post:

has_ownership() == true

Post:

length() == 0

Post:

maximum() == 0

inline LoanableSequence(size_type max)

Pre-allocation constructor.

Creates the sequence with an initial number of allocated elements. When the input parameter is less than or equal to 0, the behavior is equivalent to the default constructor. Otherwise, the post-conditions below will apply.

Parameters:

max[in] Number of elements to pre-allocate.

Post:

buffer() != nullptr

Post:

has_ownership() == true

Post:

length() == 0

Post:

maximum() == max

inline ~LoanableSequence()

Deallocate this sequence’s buffer.

Pre:

has_ownership() == true. If this precondition is not met, no memory will be released and a warning will be logged.

Post:

maximum() == 0 and the underlying buffer is released.

inline LoanableSequence(const LoanableSequence &other)

Construct a sequence with the contents of another sequence.

This method performs a deep copy of the sequence received into this one. Allocations will happen when other.length() > 0

Parameters:

other[in] The sequence from where contents are to be copied.

Post:

has_ownership() == true

Post:

maximum() == other.length()

Post:

length() == other.length()

Post:

buffer() != nullptr when other.length() > 0

inline LoanableSequence &operator=(const LoanableSequence &other)

Copy the contents of another sequence into this one.

This method performs a deep copy of the sequence received into this one. If this sequence had a buffer loaned, it will behave as if unloan has been called. Allocations will happen when (a) has_ownership() == false and other.length() > 0 (b) has_ownership() == true and other.length() > maximum()

Parameters:

other[in] The sequence from where contents are to be copied.

Post:

has_ownership() == true

Post:

maximum() >= other.length()

Post:

length() == other.length()

Post:

buffer() != nullptr when other.length() > 0

FASTDDS_SEQUENCE(FooSeq, Foo) using FooSeq = eprosima::fastdds::dds::LoanableSequence<Foo>
20.1.1.7. Policy
20.1.1.7.1. DataRepresentationId
enum eprosima::fastdds::dds::DataRepresentationId

Enum DataRepresentationId, different kinds of topic data representation

Values:

enumerator XCDR_DATA_REPRESENTATION

Extended CDR Encoding version 1.

enumerator XML_DATA_REPRESENTATION

XML Data Representation (Unsupported)

enumerator XCDR2_DATA_REPRESENTATION

Extended CDR Encoding version 2.

constexpr DataRepresentationId_t eprosima::fastdds::dds::DEFAULT_DATA_REPRESENTATION = {DataRepresentationId_t::XCDR_DATA_REPRESENTATION}

Default DataRepresentationId used in Fast DDS.

20.1.1.7.2. DataRepresentationQosPolicy
class DataRepresentationQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

With multiple standard data Representations available, and vendor-specific extensions possible, DataWriters and DataReaders must be able to negotiate which data representation(s) to use. This negotiation shall occur based on DataRepresentationQosPolicy.

Note

Immutable Qos Policy

Warning

If a writer’s offered representation is contained within a reader’s sequence, the offer satisfies the request and the policies are compatible. Otherwise, they are incompatible.

Public Functions

inline DataRepresentationQosPolicy()

Constructor.

virtual ~DataRepresentationQosPolicy() override = default

Destructor.

inline bool operator==(const DataRepresentationQosPolicy &b) const

Compares the given policy to check if it’s equal.

Parameters:

b – QoS Policy.

Returns:

True if the policy is equal.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

std::vector<DataRepresentationId_t> m_value

List of DataRepresentationId

.

By default, empty list.

20.1.1.7.3. DataSharingQosPolicy
class DataSharingQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Qos Policy to configure the data sharing

Note

Immutable Qos Policy

Public Functions

inline DataSharingQosPolicy()

Constructor.

virtual ~DataSharingQosPolicy() = default

Destructor.

inline DataSharingQosPolicy(const DataSharingQosPolicy &b)

Copy constructor.

Parameters:

b – Another DataSharingQosPolicy instance

inline virtual void clear() override

Clears the QosPolicy object.

inline const DataSharingKind &kind() const
Returns:

the current DataSharing configuration mode

inline const std::string &shm_directory() const
Returns:

the current DataSharing shared memory directory

inline const std::vector<uint64_t> &domain_ids() const

Gets the set of DataSharing domain IDs.

Each domain ID is 64 bit long. However, user-defined domain IDs are only 16 bit long, while the rest of the 48 bits are used for the automatically generated domain ID (if any).

  • Automatic domain IDs use the 48 MSB and leave the 16 LSB as zero.

  • User defined domain IDs use the 16 LSB and leave the 48 MSB as zero.

Returns:

the current DataSharing domain IDs

inline void set_max_domains(uint32_t size)
Parameters:

size – the new maximum number of domain IDs

inline const uint32_t &max_domains() const
Returns:

the current configured maximum number of domain IDs

inline void automatic()

Configures the DataSharing in automatic mode.

The default shared memory directory of the OS is used. A default domain ID is automatically computed.

inline void automatic(const std::vector<uint16_t> &domain_ids)

Configures the DataSharing in automatic mode.

The default shared memory directory of the OS is used.

Parameters:

domain_ids – the user configured DataSharing domain IDs (16 bits).

inline void automatic(const std::string &directory)

Configures the DataSharing in automatic mode.

A default domain ID is automatically computed.

Parameters:

directory – The shared memory directory to use.

inline void automatic(const std::string &directory, const std::vector<uint16_t> &domain_ids)

Configures the DataSharing in automatic mode.

Parameters:
  • directory – The shared memory directory to use.

  • domain_ids – the user configured DataSharing domain IDs (16 bits).

inline void on(const std::string &directory)

Configures the DataSharing in active mode.

A default domain ID is automatically computed.

Parameters:

directory – The shared memory directory to use. It is mandatory to provide a non-empty name or the creation of endpoints will fail.

inline void on(const std::string &directory, const std::vector<uint16_t> &domain_ids)

Configures the DataSharing in active mode.

Parameters:
  • directory – The shared memory directory to use. It is mandatory to provide a non-empty name or the creation of endpoints will fail.

  • domain_ids – the user configured DataSharing domain IDs (16 bits).

inline void off()

Configures the DataSharing in disabled mode.

inline void add_domain_id(uint16_t id)

Adds a user-specific DataSharing domain ID.

Parameters:

id – 16 bit identifier

inline rtps::ThreadSettings &data_sharing_listener_thread()

Getter for DataSharing listener thread ThreadSettings

Returns:

rtps::ThreadSettings reference

inline const rtps::ThreadSettings &data_sharing_listener_thread() const

Getter for DataSharing listener thread ThreadSettings

Returns:

rtps::ThreadSettings reference

inline void data_sharing_listener_thread(const rtps::ThreadSettings &value)

Setter for the DataSharing listener thread ThreadSettings

Parameters:

value – New ThreadSettings to be set

20.1.1.7.4. DataSharingKind
enum eprosima::fastdds::dds::DataSharingKind

Data sharing configuration kinds

Values:

enumerator AUTO

Automatic configuration. DataSharing will be used if requirements are met.

enumerator ON

Activate the use of DataSharing. Entity creation will fail if requirements for DataSharing are not met

enumerator OFF

Disable the use of DataSharing

20.1.1.7.5. DeadlineQosPolicy
class DeadlineQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

DataReader expects a new sample updating the value of each instance at least once every deadline period. DataWriter indicates that the application commits to write a new value (using the DataWriter) for each instance managed by the DataWriter at least once every deadline period.

Note

Mutable Qos Policy

Public Functions

inline DeadlineQosPolicy()

Constructor.

virtual ~DeadlineQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

fastdds::dds::Duration_t period

Maximum time expected between samples. It is inconsistent for a DataReader to have a DEADLINE period less than its TimeBasedFilterQosPolicy

minimum_separation.

By default, c_TimeInifinite.

20.1.1.7.6. DestinationOrderQosPolicy
class DestinationOrderQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Controls the criteria used to determine the logical order among changes made by Publisher entities to the same instance of data (i.e., matching Topic and key).

Note

Immutable Qos Policy

Warning

This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Public Functions

inline DestinationOrderQosPolicy()

Constructor.

virtual ~DestinationOrderQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

DestinationOrderQosPolicyKind kind

DestinationOrderQosPolicyKind.

By default, BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS.

20.1.1.7.7. DestinationOrderQosPolicyKind
enum eprosima::fastdds::dds::DestinationOrderQosPolicyKind

Enum DestinationOrderQosPolicyKind, different kinds of destination order for DestinationOrderQosPolicy.

Values:

enumerator BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS

Indicates that data is ordered based on the reception time at each Subscriber. Since each subscriber may receive the data at different times there is no guaranteed that the changes will be seen in the same order. Consequently, it is possible for each subscriber to end up with a different final value for the data.

enumerator BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS

Indicates that data is ordered based on a timestamp placed at the source (by the Service or by the application). In any case this guarantees a consistent final value for the data in all subscribers.

20.1.1.7.8. DisablePositiveACKsQosPolicy
class DisablePositiveACKsQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Class DisablePositiveACKsQosPolicy to disable sending of positive ACKs

Note

Immutable Qos Policy

Public Functions

inline DisablePositiveACKsQosPolicy()

Constructor.

virtual ~DisablePositiveACKsQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

bool enabled

True if this QoS is enabled.

By default, false.

fastdds::dds::Duration_t duration

The duration to keep samples for (not serialized as not needed by reader).

By default,

dds::c_TimeInfinite.

20.1.1.7.9. DurabilityQosPolicy
class DurabilityQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

This policy expresses if the data should ‘outlive’ their writing time.

Note

Immutable Qos Policy

Public Functions

inline DurabilityQosPolicy()

Constructor.

virtual ~DurabilityQosPolicy() = default

Destructor.

inline fastdds::rtps::DurabilityKind_t durabilityKind() const

Translates kind to rtps layer equivalent

Returns:

fastdds::rtps::DurabilityKind_t

inline void durabilityKind(const fastdds::rtps::DurabilityKind_t new_kind)

Set kind passing the rtps layer equivalent kind

Parameters:

new_kind – fastdds::rtps::DurabilityKind_t

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

DurabilityQosPolicyKind_t kind

DurabilityQosPolicyKind.

By default the value for DataReaders: VOLATILE_DURABILITY_QOS, for DataWriters TRANSIENT_LOCAL_DURABILITY_QOS.

20.1.1.7.10. DurabilityQosPolicyKind
enum eprosima::fastdds::dds::DurabilityQosPolicyKind

Enum DurabilityQosPolicyKind_t, different kinds of durability for DurabilityQosPolicy.

Values:

enumerator VOLATILE_DURABILITY_QOS

The Service does not need to keep any samples of data-instances on behalf of any DataReader that is not known by the DataWriter at the time the instance is written. In other words the Service will only attempt to provide the data to existing subscribers

enumerator TRANSIENT_LOCAL_DURABILITY_QOS

For TRANSIENT_LOCAL, the service is only required to keep the data in the memory of the DataWriter that wrote the data and the data is not required to survive the DataWriter.

enumerator TRANSIENT_DURABILITY_QOS

For TRANSIENT, the service is only required to keep the data in memory and not in permanent storage; but the data is not tied to the lifecycle of the DataWriter and will, in general, survive it.

enumerator PERSISTENT_DURABILITY_QOS

Data is kept on permanent storage, so that they can outlive a system session.

Warning

Not Supported

20.1.1.7.11. DurabilityServiceQosPolicy
class DurabilityServiceQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Specifies the configuration of the durability service. That is, the service that implements the DurabilityQosPolicy kind of TRANSIENT and PERSISTENT.

Note

Immutable Qos Policy

Warning

This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Public Functions

inline DurabilityServiceQosPolicy()

Constructor.

virtual ~DurabilityServiceQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

fastdds::dds::Duration_t service_cleanup_delay

Control when the service is able to remove all information regarding a data-instance.

By default,

dds::c_TimeZero.

HistoryQosPolicyKind history_kind

Controls the HistoryQosPolicy of the fictitious DataReader

that stores the data within the durability service.

By default, KEEP_LAST_HISTORY_QOS.

int32_t history_depth

Number of most recent values that should be maintained on the History. It only have effect if the history_kind is KEEP_LAST_HISTORY_QOS.

By default, 1.

int32_t max_samples

Control the ResourceLimitsQos of the implied DataReader that stores the data within the durability service. Specifies the maximum number of data-samples the DataWriter (or DataReader) can manage across all the instances associated with it. Represents the maximum samples the middleware can store for any one DataWriter (or DataReader

). It is inconsistent for this value to be less than max_samples_per_instance.

By default, LENGTH_UNLIMITED.

int32_t max_instances

Control the ResourceLimitsQos of the implied DataReader that stores the data within the durability service. Represents the maximum number of instances DataWriter (or DataReader

) can manage.

By default, LENGTH_UNLIMITED.

int32_t max_samples_per_instance

Control the ResourceLimitsQos of the implied DataReader

that stores the data within the durability service. Represents the maximum number of samples of any one instance a DataWriter(or DataReader) can manage. It is inconsistent for this value to be greater than max_samples.

By default, LENGTH_UNLIMITED.

20.1.1.7.12. EntityFactoryQosPolicy
class EntityFactoryQosPolicy

Controls the behavior of the entity when acting as a factory for other entities. In other words, configures the side-effects of the create_* and delete_* operations.

Note

Mutable Qos Policy

Public Functions

inline EntityFactoryQosPolicy()

Constructor without parameters.

inline EntityFactoryQosPolicy(bool autoenable)

Constructor.

Parameters:

autoenable – Value for the autoenable_created_entities boolean

inline virtual ~EntityFactoryQosPolicy()

Destructor.

Public Members

bool autoenable_created_entities

Specifies whether the entity acting as a factory automatically enables the instances it creates. If True the factory will automatically enable each created Entity

otherwise it will not.

By default, True.

20.1.1.7.13. GenericDataQosPolicy
class GenericDataQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy, public eprosima::fastdds::ResourceLimitedVector<fastdds::rtps::octet>

Class GenericDataQosPolicy, base class to transmit user data during the discovery phase.

Subclassed by eprosima::fastdds::dds::GroupDataQosPolicy, eprosima::fastdds::dds::TopicDataQosPolicy, eprosima::fastdds::dds::UserDataQosPolicy

Public Functions

inline GenericDataQosPolicy(const GenericDataQosPolicy &data)

Construct from another GenericDataQosPolicy.

The resulting GenericDataQosPolicy will have the same size limits as the input attribute

Parameters:

data – data to copy in the newly created object

inline GenericDataQosPolicy(ParameterId_t pid, const collection_type &data)

Construct from underlying collection type.

Useful to easy integration on old APIs where a traditional container was used. The resulting GenericDataQosPolicy will always be unlimited in size

Parameters:
  • pid – Id of the parameter

  • data – data to copy in the newly created object

inline GenericDataQosPolicy &operator=(const collection_type &b)

Copies data from underlying collection type.

Useful to easy integration on old APIs where a traditional container was used. The resulting GenericDataQosPolicy will keep the current size limit. If the input data is larger than the current limit size, the elements exceeding that maximum will be silently discarded.

Parameters:

b – object to be copied

Returns:

reference to the current object.

inline GenericDataQosPolicy &operator=(const GenericDataQosPolicy &b)

Copies another GenericDataQosPolicy.

The resulting GenericDataQosPolicy will have the same size limit as the input parameter, so all data in the input will be copied.

Parameters:

b – object to be copied

Returns:

reference to the current object.

inline void set_max_size(size_t size)

Set the maximum size of the user data and reserves memory for that much.

Parameters:

size – new maximum size of the user data. Zero for unlimited size

inline const collection_type &dataVec() const
Returns:

const reference to the internal raw data.

inline virtual void clear() override

Clears the QosPolicy object.

inline const collection_type &data_vec() const

Returns raw data vector.

Returns:

raw data as vector of octets.

inline collection_type &data_vec()

Returns raw data vector.

Returns:

raw data as vector of octets.

inline void data_vec(const collection_type &vec)

Sets raw data vector.

Parameters:

vec – raw data to set.

inline const collection_type &getValue() const

Returns raw data vector.

Returns:

raw data as vector of octets.

inline void setValue(const collection_type &vec)

Sets raw data vector.

Parameters:

vec – raw data to set.

20.1.1.7.14. GroupDataQosPolicy
class GroupDataQosPolicy : public eprosima::fastdds::dds::GenericDataQosPolicy

Class derived from GenericDataQosPolicy.

The purpose of this QoS is to allow the application to attach additional information to the created Publisher or Subscriber. The value of the GROUP_DATA is available to the application on the DataReader and DataWriter entities and is propagated by means of the built-in topics.

This QoS can be used by an application combination with the DataReaderListener and DataWriterListener to implement matching policies similar to those of the PARTITION QoS except the decision can be made based on an application-defined policy.

20.1.1.7.15. HistoryQosPolicy
class HistoryQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Specifies the behavior of the Service in the case where the value of a sample changes (one or more times) before it can be successfully communicated to one or more existing subscribers. This QoS policy controls whether the Service should deliver only the most recent value, attempt to deliver all intermediate values, or do something in between. On the publishing side this policy controls the samples that should be maintained by the DataWriter on behalf of existing DataReader entities. The behavior with regards to a DataReaderentities discovered after a sample is written is controlled by the DURABILITY QoS policy. On the subscribing side it controls the samples that should be maintained until the application “takes” them from the Service.

Note

Immutable Qos Policy

Public Functions

inline HistoryQosPolicy()

Constructor.

virtual ~HistoryQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

HistoryQosPolicyKind kind

HistoryQosPolicyKind.

By default, KEEP_LAST_HISTORY_QOS.

int32_t depth

History depth.

By default, 1. If a value other than 1 is specified, it should be consistent with the settings of the ResourceLimitsQosPolicy.

Warning

Only takes effect if the kind is KEEP_LAST_HISTORY_QOS.

20.1.1.7.16. HistoryQosPolicyKind
enum eprosima::fastdds::dds::HistoryQosPolicyKind

Enum HistoryQosPolicyKind, different kinds of History Qos for HistoryQosPolicy.

Values:

enumerator KEEP_LAST_HISTORY_QOS

On the publishing side, the Service will only attempt to keep the most recent “depth” samples of each instance of data (identified by its key) managed by the DataWriter. On the subscribing side, the DataReader will only attempt to keep the most recent “depth” samples received for each instance (identified by its key) until the application “takes” them via the DataReader’s take operation.

enumerator KEEP_ALL_HISTORY_QOS

On the publishing side, the Service will attempt to keep all samples (representing each value written) of each instance of data (identified by its key) managed by the DataWriter until they can be delivered to all subscribers. On the subscribing side, the Service will attempt to keep all samples of each instance of data (identified by its key) managed by the DataReader. These samples are kept until the application “takes” them from the Service via the take operation.

20.1.1.7.17. LatencyBudgetQosPolicy
class LatencyBudgetQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Specifies the maximum acceptable delay from the time the data is written until the data is inserted in the receiver’s application-cache and the receiving application is notified of the fact.This policy is a hint to the Service, not something that must be monitored or enforced. The Service is not required to track or alert the user of any violation.

Note

Mutable Qos Policy

Warning

This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Public Functions

inline LatencyBudgetQosPolicy()

Constructor.

virtual ~LatencyBudgetQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

fastdds::dds::Duration_t duration

Maximum acceptable delay from the time data is written until it is received.

By default,

dds::c_TimeZero.

20.1.1.7.18. LifespanQosPolicy
class LifespanQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Specifies the maximum duration of validity of the data written by the DataWriter.

Note

Mutable Qos Policy

Public Functions

inline LifespanQosPolicy()

Constructor.

virtual ~LifespanQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

fastdds::dds::Duration_t duration

Period of validity.

By default,

dds::c_TimeInfinite.

20.1.1.7.19. LivelinessQosPolicy
class LivelinessQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Determines the mechanism and parameters used by the application to determine whether an Entity is “active” (alive). The “liveliness” status of an Entity is used to maintain instance ownership in combination with the setting of the OwnershipQosPolicy. The application is also informed via listener when an Entity is no longer alive.

The DataReader requests that liveliness of the writers is maintained by the requested means and loss of liveliness is detected with delay not to exceed the lease_duration.

The DataWriter commits to signaling its liveliness using the stated means at intervals not to exceed the lease_duration. Listeners are used to notify the DataReaderof loss of liveliness and DataWriter of violations to the liveliness contract.

Public Functions

inline LivelinessQosPolicy()

Constructor.

virtual ~LivelinessQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

LivelinessQosPolicyKind kind

Liveliness kind

By default, AUTOMATIC_LIVELINESS.

fastdds::dds::Duration_t lease_duration

Period within which liveliness should be asserted.

On a DataWriter it represents the period it commits to signal its liveliness. On a DataReader it represents the period without assertion after which a DataWriter is considered inactive. By default, dds::c_TimeInfinite.

fastdds::dds::Duration_t announcement_period

The period for automatic assertion of liveliness.

Only used for DataWriters with AUTOMATIC liveliness. By default, dds::c_TimeInfinite.

Warning

When not infinite, must be < lease_duration, and it is advisable to be less than 0.7*lease_duration.

20.1.1.7.20. LivelinessQosPolicyKind
enum eprosima::fastdds::dds::LivelinessQosPolicyKind

Enum LivelinessQosPolicyKind, different kinds of liveliness for LivelinessQosPolicy

Values:

enumerator AUTOMATIC_LIVELINESS_QOS

The infrastructure will automatically signal liveliness for the DataWriters at least as often as required by the lease_duration.

enumerator MANUAL_BY_PARTICIPANT_LIVELINESS_QOS

The Service will assume that as long as at least one Entity within the DomainParticipant has asserted its liveliness the other Entities in that same DomainParticipant are also alive.

enumerator MANUAL_BY_TOPIC_LIVELINESS_QOS

The Service will only assume liveliness of the DataWriter if the application has asserted liveliness of that DataWriter itself.

20.1.1.7.21. OwnershipQosPolicy
class OwnershipQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Specifies whether it is allowed for multiple DataWriters to write the same instance of the data and if so, how these modifications should be arbitrated

Note

Immutable Qos Policy

Public Functions

inline OwnershipQosPolicy()

Constructor.

virtual ~OwnershipQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

OwnershipQosPolicyKind kind

OwnershipQosPolicyKind.

20.1.1.7.22. OwnershipQosPolicyKind
enum eprosima::fastdds::dds::OwnershipQosPolicyKind

Enum OwnershipQosPolicyKind, different kinds of ownership for OwnershipQosPolicy.

Values:

enumerator SHARED_OWNERSHIP_QOS

Indicates shared ownership for each instance. Multiple writers are allowed to update the same instance and all the updates are made available to the readers. In other words there is no concept of an “owner” for the instances.

enumerator EXCLUSIVE_OWNERSHIP_QOS

Indicates each instance can only be owned by one DataWriter, but the owner of an instance can change dynamically. The selection of the owner is controlled by the setting of the OwnershipStrengthQosPolicy. The owner is always set to be the highest-strength DataWriter object among the ones currently “active” (as determined by the LivelinessQosPolicy).

20.1.1.7.23. OwnershipStrengthQosPolicy
class OwnershipStrengthQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Specifies the value of the “strength” used to arbitrate among multiple DataWriter objects that attempt to modify the same instance of a data-object (identified by Topic + key).This policy only applies if the OWNERSHIP QoS policy is of kind EXCLUSIVE.

Note

Mutable Qos Policy

Public Functions

inline OwnershipStrengthQosPolicy()

Constructor.

virtual ~OwnershipStrengthQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

uint32_t value

Strength

By default, 0.

20.1.1.7.24. ParticipantResourceLimitsQos
using eprosima::fastdds::dds::ParticipantResourceLimitsQos = fastdds::rtps::RTPSParticipantAllocationAttributes

Holds allocation limits affecting collections managed by a participant.

20.1.1.7.25. Partition_t
class Partition_t

Public Functions

inline explicit Partition_t(const void *ptr)

Constructor using a pointer.

Parameters:

ptr – Pointer to be set

inline uint32_t size() const

Getter for the size.

Returns:

uint32_t with the size

inline const char *name() const

Getter for the partition name.

Returns:

name

20.1.1.7.26. PartitionQosPolicy
class PartitionQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Set of strings that introduces a logical partition among the topics visible by the Publisher and Subscriber. A DataWriter within a Publisher only communicates with a DataReader in a Subscriber if (in addition to matching the Topic and having compatible QoS) the Publisher and Subscriber have a common partition name string.

The empty string (“”) is considered a valid partition that is matched with other partition names using the same rules of string matching and regular-expression matching used for any other partition name.

Note

Mutable Qos Policy

Public Functions

inline PartitionQosPolicy()

Constructor without parameters.

inline PartitionQosPolicy(uint16_t in_length)

Constructor using Parameter length.

Parameters:

in_length – Length of the parameter

inline PartitionQosPolicy(const PartitionQosPolicy &b)

Copy constructor.

Parameters:

b – Another PartitionQosPolicy instance

virtual ~PartitionQosPolicy() = default

Destructor.

inline const_iterator begin() const

Getter for the first position of the partition list.

Returns:

const_iterator

inline const_iterator end() const

Getter for the end of the partition list.

Returns:

const_iterator

inline uint32_t size() const

Getter for the number of partitions.

Returns:

uint32_t with the size

inline uint32_t empty() const

Check if the set is empty.

Returns:

true if it is empty, false otherwise

inline void set_max_size(uint32_t size)

Setter for the maximum size reserved for partitions (in bytes)

Parameters:

size – Size to be set

inline uint32_t max_size() const

Getter for the maximum size (in bytes)

Returns:

uint32_t with the maximum size

inline void push_back(const char *name)

Appends a name to the list of partition names.

Parameters:

name – Name to append.

inline virtual void clear() override

Clears list of partition names

inline const std::vector<std::string> getNames() const

Returns partition names.

Returns:

Vector of partition name strings.

inline void setNames(std::vector<std::string> &nam)

Overrides partition names

Parameters:

nam – Vector of partition name strings.

inline const std::vector<std::string> names() const

Returns partition names.

Returns:

Vector of partition name strings.

inline void names(std::vector<std::string> &nam)

Overrides partition names

Parameters:

nam – Vector of partition name strings.

class const_iterator

Public Functions

inline const_iterator(const fastdds::rtps::octet *ptr)

Constructor using a pointer.

Parameters:

ptr – Pointer to be set

20.1.1.7.27. PresentationQosPolicy
class PresentationQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Specifies how the samples representing changes to data instances are presented to the subscribing application. This policy affects the application’s ability to specify and receive coherent changes and to see the relative order of changes.access_scope determines the largest scope spanning the entities for which the order and coherency of changes can be preserved. The two booleans control whether coherent access and ordered access are supported within the scope access_scope.

Note

Immutable Qos Policy

Warning

This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Public Functions

inline PresentationQosPolicy()

Constructor without parameters.

virtual ~PresentationQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

PresentationQosPolicyAccessScopeKind access_scope

Access Scope Kind

By default, INSTANCE_PRESENTATION_QOS.

bool coherent_access

Specifies support coherent access. That is, the ability to group a set of changes as a unit on the publishing end such that they are received as a unit at the subscribing end. by default, false.

bool ordered_access

Specifies support for ordered access to the samples received at the subscription end. That is, the ability of the subscriber to see changes in the same order as they occurred on the publishing end. By default, false.

20.1.1.7.28. PresentationQosPolicyAccessScopeKind
enum eprosima::fastdds::dds::PresentationQosPolicyAccessScopeKind

Enum PresentationQosPolicyAccessScopeKind, different kinds of Presentation Policy order for PresentationQosPolicy.

Values:

enumerator INSTANCE_PRESENTATION_QOS

Scope spans only a single instance. Indicates that changes to one instance need not be coherent nor ordered with respect to changes to any other instance. In other words, order and coherent changes apply to each instance separately.

enumerator TOPIC_PRESENTATION_QOS

Scope spans to all instances within the same DataWriter (or DataReader), but not across instances in different DataWriter (or DataReader).

enumerator GROUP_PRESENTATION_QOS

Scope spans to all instances belonging to DataWriter (or DataReader) entities within the same Publisher (or Subscriber).

20.1.1.7.29. PropertyPolicyQos
using eprosima::fastdds::dds::PropertyPolicyQos = fastdds::rtps::PropertyPolicy

Property policies.

20.1.1.7.30. PublishModeQosPolicy
class PublishModeQosPolicy : public eprosima::fastdds::dds::QosPolicy

Class PublishModeQosPolicy, defines the publication mode for a specific writer.

Public Functions

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

PublishModeQosPolicyKind kind = SYNCHRONOUS_PUBLISH_MODE

PublishModeQosPolicyKind

By default, SYNCHRONOUS_PUBLISH_MODE.

std::string flow_controller_name = fastdds::rtps::FASTDDS_FLOW_CONTROLLER_DEFAULT

Name of the flow controller used when publish mode kind is ASYNCHRONOUS_PUBLISH_MODE.

Since

2.4.0

20.1.1.7.31. PublishModeQosPolicyKind
enum eprosima::fastdds::dds::PublishModeQosPolicyKind

Enum PublishModeQosPolicyKind, different kinds of publication synchronism

Values:

enumerator SYNCHRONOUS_PUBLISH_MODE

Synchronous publication mode (default for writers).

enumerator ASYNCHRONOUS_PUBLISH_MODE

Asynchronous publication mode.

20.1.1.7.32. QosPolicy
class QosPolicy

Class QosPolicy, base for all QoS policies defined for Writers and Readers.

Subclassed by eprosima::fastdds::dds::DataRepresentationQosPolicy, eprosima::fastdds::dds::DataSharingQosPolicy, eprosima::fastdds::dds::DeadlineQosPolicy, eprosima::fastdds::dds::DestinationOrderQosPolicy, eprosima::fastdds::dds::DisablePositiveACKsQosPolicy, eprosima::fastdds::dds::DurabilityQosPolicy, eprosima::fastdds::dds::DurabilityServiceQosPolicy, eprosima::fastdds::dds::GenericDataQosPolicy, eprosima::fastdds::dds::HistoryQosPolicy, eprosima::fastdds::dds::LatencyBudgetQosPolicy, eprosima::fastdds::dds::LifespanQosPolicy, eprosima::fastdds::dds::LivelinessQosPolicy, eprosima::fastdds::dds::OwnershipQosPolicy, eprosima::fastdds::dds::OwnershipStrengthQosPolicy, eprosima::fastdds::dds::PartitionQosPolicy, eprosima::fastdds::dds::PresentationQosPolicy, eprosima::fastdds::dds::PublishModeQosPolicy, eprosima::fastdds::dds::ReliabilityQosPolicy, eprosima::fastdds::dds::ResourceLimitsQosPolicy, eprosima::fastdds::dds::TimeBasedFilterQosPolicy, eprosima::fastdds::dds::TransportConfigQos, eprosima::fastdds::dds::TransportPriorityQosPolicy, eprosima::fastdds::dds::TypeConsistencyEnforcementQosPolicy, eprosima::fastdds::dds::TypeIdV1, eprosima::fastdds::dds::TypeObjectV1, eprosima::fastdds::dds::WireProtocolConfigQos, eprosima::fastdds::dds::xtypes::TypeInformationParameter

Public Functions

inline QosPolicy()

Constructor without parameters.

inline explicit QosPolicy(bool send_always)

Constructor.

Parameters:

send_always – Boolean that set if the Qos need to be sent even if it is not changed

QosPolicy(const QosPolicy &b) = default

Copy Constructor.

Parameters:

b – Another instance of QosPolicy

virtual ~QosPolicy() = default

Destructor.

inline virtual bool send_always() const

Whether it should always be sent.

Returns:

True if it should always be sent.

inline virtual void clear() = 0

Clears the QosPolicy object.

Public Members

bool hasChanged

Boolean that indicates if the Qos has been changed with respect to the default Qos.

20.1.1.7.33. QosPolicyId_t
enum eprosima::fastdds::dds::QosPolicyId_t

The identifier for each QosPolicy.

Each QosPolicy class has a different ID that is then used to refer to the incompatible policies on OfferedIncompatibleQosStatus and RequestedIncompatibleQosStatus.

Values:

enumerator INVALID_QOS_POLICY_ID
enumerator USERDATA_QOS_POLICY_ID
enumerator DURABILITY_QOS_POLICY_ID
enumerator PRESENTATION_QOS_POLICY_ID
enumerator DEADLINE_QOS_POLICY_ID
enumerator LATENCYBUDGET_QOS_POLICY_ID
enumerator OWNERSHIP_QOS_POLICY_ID
enumerator OWNERSHIPSTRENGTH_QOS_POLICY_ID
enumerator LIVELINESS_QOS_POLICY_ID
enumerator TIMEBASEDFILTER_QOS_POLICY_ID
enumerator PARTITION_QOS_POLICY_ID
enumerator RELIABILITY_QOS_POLICY_ID
enumerator DESTINATIONORDER_QOS_POLICY_ID
enumerator HISTORY_QOS_POLICY_ID
enumerator RESOURCELIMITS_QOS_POLICY_ID
enumerator ENTITYFACTORY_QOS_POLICY_ID
enumerator WRITERDATALIFECYCLE_QOS_POLICY_ID
enumerator READERDATALIFECYCLE_QOS_POLICY_ID
enumerator TOPICDATA_QOS_POLICY_ID
enumerator GROUPDATA_QOS_POLICY_ID
enumerator TRANSPORTPRIORITY_QOS_POLICY_ID
enumerator LIFESPAN_QOS_POLICY_ID
enumerator DURABILITYSERVICE_QOS_POLICY_ID
enumerator DATAREPRESENTATION_QOS_POLICY_ID
enumerator TYPECONSISTENCYENFORCEMENT_QOS_POLICY_ID
enumerator DISABLEPOSITIVEACKS_QOS_POLICY_ID
enumerator PARTICIPANTRESOURCELIMITS_QOS_POLICY_ID
enumerator PROPERTYPOLICY_QOS_POLICY_ID
enumerator PUBLISHMODE_QOS_POLICY_ID
enumerator READERRESOURCELIMITS_QOS_POLICY_ID
enumerator RTPSENDPOINT_QOS_POLICY_ID
enumerator RTPSRELIABLEREADER_QOS_POLICY_ID
enumerator RTPSRELIABLEWRITER_QOS_POLICY_ID
enumerator TRANSPORTCONFIG_QOS_POLICY_ID
enumerator TYPECONSISTENCY_QOS_POLICY_ID
enumerator WIREPROTOCOLCONFIG_QOS_POLICY_ID
enumerator WRITERRESOURCELIMITS_QOS_POLICY_ID
enumerator NEXT_QOS_POLICY_ID
20.1.1.7.34. ReaderDataLifecycleQosPolicy
class ReaderDataLifecycleQosPolicy

Specifies the behavior of the DataReader with regards to the lifecycle of the data-instances it manages.

Note

Mutable Qos Policy

Warning

This Qos Policy will be implemented in future releases.

Public Functions

inline ReaderDataLifecycleQosPolicy()

Constructor.

inline virtual ~ReaderDataLifecycleQosPolicy()

Destructor.

Public Members

dds::Duration_t autopurge_no_writer_samples_delay

Indicates the duration the DataReader

must retain information regarding instances that have the instance_state NOT_ALIVE_NO_WRITERS.

By default,

dds::c_TimeInfinite.

dds::Duration_t autopurge_disposed_samples_delay

Indicates the duration the DataReader

must retain information regarding instances that have the instance_state NOT_ALIVE_DISPOSED.

By default,

dds::c_TimeInfinite.

20.1.1.7.35. ReliabilityQosPolicy
class ReliabilityQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Indicates the reliability of the endpoint.

Note

Immutable Qos Policy

Public Functions

inline ReliabilityQosPolicy()

Constructor.

virtual ~ReliabilityQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

ReliabilityQosPolicyKind kind

Defines the reliability kind of the endpoint.

By default, BEST_EFFORT_RELIABILITY_QOS for DataReaders and RELIABLE_RELIABILITY_QOS for DataWriters.

fastdds::dds::Duration_t max_blocking_time

Defines the maximum period of time certain methods will be blocked.

Methods affected by this property are:

  • DataWriter::write

  • DataReader::takeNextData

  • DataReader::readNextData

    By default, 100 ms.

20.1.1.7.36. ReliabilityQosPolicyKind
enum eprosima::fastdds::dds::ReliabilityQosPolicyKind

Enum ReliabilityQosPolicyKind, different kinds of reliability for ReliabilityQosPolicy.

Values:

enumerator BEST_EFFORT_RELIABILITY_QOS

Indicates that it is acceptable to not retry propagation of any samples. Presumably new values for the samples are generated often enough that it is not necessary to re-send or acknowledge any samples

enumerator RELIABLE_RELIABILITY_QOS

Specifies the Service will attempt to deliver all samples in its history. Missed samples may be retried. In steady-state (no modifications communicated via the DataWriter) the middleware guarantees that all samples in the DataWriter history will eventually be delivered to all the DataReader objects. Outside steady state the HistoryQosPolicy and ResourceLimitsQosPolicy will determine how samples become part of the history and whether samples can be discarded from it.

20.1.1.7.37. ResourceLimitsQosPolicy
class ResourceLimitsQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Specifies the resources that the Service can consume in order to meet the requested QoS

Note

Immutable Qos Policy

Public Functions

inline ResourceLimitsQosPolicy()

Constructor.

virtual ~ResourceLimitsQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

int32_t max_samples

Specifies the maximum number of data-samples the DataWriter (or DataReader) can manage across all the instances associated with it. Represents the maximum samples the middleware can store for any one DataWriter (or DataReader

).

Value less or equal to 0 means infinite resources. By default, 5000.

Warning

It is inconsistent if max_samples < (max_instances * max_samples_per_instance).

int32_t max_instances

Represents the maximum number of instances DataWriter (or DataReader

) can manage.

Value less or equal to 0 means infinite resources. By default, 10.

Warning

It is inconsistent if (max_instances * max_samples_per_instance) > max_samples.

int32_t max_samples_per_instance

Represents the maximum number of samples of any one instance a DataWriter(or DataReader) can manage.

Value less or equal to 0 means infinite resources. By default, 400.

Warning

It is inconsistent if (max_instances * max_samples_per_instance) > max_samples.

int32_t allocated_samples

Number of samples currently allocated.

By default, 100.

int32_t extra_samples

Represents the extra number of samples available once the max_samples have been reached in the history. This makes it possible, for example, to loan samples even with a full history. By default, 1.

20.1.1.7.38. RTPSEndpointQos
class RTPSEndpointQos

Qos Policy to configure the endpoint.

Public Members

rtps::LocatorList unicast_locator_list

Unicast locator list.

rtps::LocatorList multicast_locator_list

Multicast locator list.

rtps::LocatorList remote_locator_list

Remote locator list.

fastdds::rtps::ExternalLocators external_unicast_locators

The collection of external locators to use for communication.

bool ignore_non_matching_locators = false

Whether locators that don’t match with the announced locators should be kept.

int16_t user_defined_id = -1

User Defined ID, used for StaticEndpointDiscovery.

By default, -1.

int16_t entity_id = -1

Entity

ID, if the user wants to specify the EntityID of the endpoint.

By default, -1.

fastdds::rtps::MemoryManagementPolicy_t history_memory_policy = fastdds::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE

Underlying History memory policy.

By default, PREALLOCATED_WITH_REALLOC_MEMORY_MODE.

20.1.1.7.39. TimeBasedFilterQosPolicy
class TimeBasedFilterQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Filter that allows a DataReader to specify that it is interested only in (potentially) a subset of the values of the data. The filter states that the DataReader does not want to receive more than one value each minimum_separation, regardless of how fast the changes occur. It is inconsistent for a DataReader to have a minimum_separation longer than its Deadline period.

Note

Mutable Qos Policy

Warning

This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Public Functions

inline TimeBasedFilterQosPolicy()

Constructor.

virtual ~TimeBasedFilterQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

fastdds::dds::Duration_t minimum_separation

Minimum interval between samples. By default, dds::c_TimeZero (the DataReader is interested in all values)

20.1.1.7.40. TopicDataQosPolicy
class TopicDataQosPolicy : public eprosima::fastdds::dds::GenericDataQosPolicy

Class derived from GenericDataQosPolicy.

The purpose of this QoS is to allow the application to attach additional information to the created Topic such that when a remote application discovers their existence it can examine the information and use it in an application-defined way.

In combination with the listeners on the DataReader and DataWriter as well as by means of operations such as ignore_topic,these QoS can assist an application to extend the provided QoS.

20.1.1.7.41. TransportConfigQos
class TransportConfigQos : public eprosima::fastdds::dds::QosPolicy

Qos Policy to configure the transport layer.

Public Functions

inline TransportConfigQos()

Constructor.

virtual ~TransportConfigQos() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

std::vector<std::shared_ptr<fastdds::rtps::TransportDescriptorInterface>> user_transports

User defined transports to use alongside or in place of builtins.

bool use_builtin_transports

Set as false to disable the default UDPv4 implementation.

By default, true.

uint32_t send_socket_buffer_size

Send socket buffer size for the send resource.

Zero value indicates to use default system buffer size.

By default, 0.

uint32_t listen_socket_buffer_size

Listen socket buffer for all listen resources.

Zero value indicates to use default system buffer size.

By default, 0.

rtps::ThreadSettings builtin_transports_reception_threads_

Thread settings for the builtin transports reception threads.

uint32_t max_msg_size_no_frag

Maximum message size used to avoid fragmentation, set ONLY in LARGE_DATA.

If this value is not zero, the network factory will allow the initialization of UDP transports with maxMessageSize higher than 65500K.

fastdds::rtps::NetmaskFilterKind netmask_filter

Netmask filter configuration.

20.1.1.7.42. TransportPriorityQosPolicy
class TransportPriorityQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

This policy is a hint to the infrastructure as to how to set the priority of the underlying transport used to send the data.

Note

Mutable Qos Policy

Warning

This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Public Functions

inline TransportPriorityQosPolicy()

Constructor.

virtual ~TransportPriorityQosPolicy() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

uint32_t value

Priority

By default, 0.

20.1.1.7.43. TypeConsistencyEnforcementQosPolicy
class TypeConsistencyEnforcementQosPolicy : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

The TypeConsistencyEnforcementQosPolicy defines the rules for determining whether the type used to publish a given data stream is consistent with that used to subscribe to it. It applies to DataReaders.

Note

Immutable Qos Policy

Public Functions

inline TypeConsistencyEnforcementQosPolicy()

Constructor.

virtual ~TypeConsistencyEnforcementQosPolicy() override = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

Public Members

TypeConsistencyKind m_kind

TypeConsistencyKind.

By default, ALLOW_TYPE_COERCION.

bool m_ignore_sequence_bounds

This option controls whether sequence bounds are taken into consideration for type assignability. If the option is set to TRUE, sequence bounds (maximum lengths) are not considered as part of the type assignability. This means that a T2 sequence type with maximum length L2 would be assignable to a T1 sequence type with maximum length L1, even if L2 is greater than L1. If the option is set to false, then sequence bounds are taken into consideration for type assignability and in order for T1 to be assignable from T2 it is required that L1>= L2.

By default, true.

bool m_ignore_string_bounds

This option controls whether string bounds are taken into consideration for type assignability. If the option is set to TRUE, string bounds (maximum lengths) are not considered as part of the type assignability. This means that a T2 string type with maximum length L2 would be assignable to a T1 string type with maximum length L1, even if L2 is greater than L1. If the option is set to false, then string bounds are taken into consideration for type assignability and in order for T1 to be assignable from T2 it is required that L1>= L2.

By default, true.

bool m_ignore_member_names

This option controls whether member names are taken into consideration for type assignability. If the option is set to TRUE, member names are considered as part of assignability in addition to member IDs (so that members with the same ID also have the same name). If the option is set to FALSE, then member names are not ignored.

By default, false.

bool m_prevent_type_widening

This option controls whether type widening is allowed. If the option is set to FALSE, type widening is permitted. If the option is set to TRUE,it shall cause a wider type to not be assignable to a narrower type.

By default, false.

bool m_force_type_validation

This option requires type information to be available in order to complete matching between a DataWriter and DataReader

when set to TRUE, otherwise matching can occur without complete type information when set to FALSE.

By default, false.

20.1.1.7.44. TypeConsistencyKind
enum eprosima::fastdds::dds::TypeConsistencyKind

Values:

enumerator DISALLOW_TYPE_COERCION

The DataWriter and the DataReader must support the same data type in order for them to communicate.

enumerator ALLOW_TYPE_COERCION

The DataWriter and the DataReader need not support the same data type in order for them to communicate as long as the reader’s type is assignable from the writer’s type.

20.1.1.7.45. UserDataQosPolicy
class UserDataQosPolicy : public eprosima::fastdds::dds::GenericDataQosPolicy

Class derived from GenericDataQosPolicy.

The purpose of this QoS is to allow the application to attach additional information to the created Entity objects such that when a remote application discovers their existence it can access that information and use it for its own purposes.

One possible use of this QoS is to attach security credentials or some other information that can be used by the remote application to authenticate the source.

20.1.1.7.46. WireProtocolConfigQos
class WireProtocolConfigQos : public eprosima::fastdds::dds::QosPolicy

Qos Policy that configures the wire protocol.

Public Functions

inline WireProtocolConfigQos()

Constructor.

virtual ~WireProtocolConfigQos() = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

inline ReturnCode_t easy_mode(const std::string &ip)

Setter for ROS 2 Easy Mode IP.

Note

The IP address must be an IPv4 address. If it is not, the IP address will not be set.

Parameters:

ip – IP address to set

Returns:

RETCODE_OK if the IP address is set, an specific error code otherwise: RETCODE_BAD_PARAMETER if the IP address is not an IPv4 address.

inline const std::string &easy_mode() const

Getter for ROS 2 Easy Mode IP.

Returns:

IP address if set, empty string otherwise

Public Members

fastdds::rtps::GuidPrefix_t prefix

Optionally allows user to define the GuidPrefix_t.

int32_t participant_id

Participant ID

By default, -1.

fastdds::rtps::BuiltinAttributes builtin

Builtin parameters.

fastdds::rtps::PortParameters port

Port Parameters.

rtps::LocatorList default_unicast_locator_list

Default list of Unicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case that it was defined with NO UnicastLocators. At least ONE locator should be included in this list.

rtps::LocatorList default_multicast_locator_list

Default list of Multicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case that it was defined with NO MulticastLocators. This is usually left empty.

rtps::ExternalLocators default_external_unicast_locators

The collection of external locators to use for communication on user created topics.

bool ignore_non_matching_locators = false

Whether locators that don’t match with the announced locators should be kept.

20.1.1.7.47. WriterDataLifecycleQosPolicy
class WriterDataLifecycleQosPolicy

Specifies the behavior of the DataWriter with regards to the lifecycle of the data-instances it manages.

Note

Mutable Qos Policy

Warning

This Qos Policy will be implemented in future releases.

Public Functions

inline WriterDataLifecycleQosPolicy()

Constructor.

inline virtual ~WriterDataLifecycleQosPolicy()

Destructor.

Public Members

bool autodispose_unregistered_instances

Controls whether a DataWriter

will automatically dispose instances each time they are unregistered. The setting autodispose_unregistered_instances = TRUE indicates that unregistered instances will also be considered disposed.

By default, true.

20.1.1.7.48. WriterResourceLimitsQos
class WriterResourceLimitsQos

Qos Policy to configure the limit of the writer resources.

Public Functions

inline WriterResourceLimitsQos()

Constructor.

virtual ~WriterResourceLimitsQos() = default

Destructor.

Public Members

fastdds::ResourceLimitedContainerConfig matched_subscriber_allocation

Matched subscribers allocation limits.

fastdds::ResourceLimitedContainerConfig reader_filters_allocation

Reader filters allocation limits.

20.1.1.8. StackAllocatedSequence
template<typename T, LoanableCollection::size_type num_items>
struct StackAllocatedSequence : public eprosima::fastdds::dds::LoanableTypedCollection<T>

A type-safe, ordered collection of elements allocated on the stack.

20.1.1.9. Status
20.1.1.9.1. BaseStatus
struct BaseStatus

A struct storing the base status.

Public Members

int32_t total_count = 0

Total cumulative count.

int32_t total_count_change = 0

Increment since the last time the status was read.

20.1.1.9.2. DeadlineMissedStatus
struct DeadlineMissedStatus

A struct storing the deadline status.

Public Functions

inline DeadlineMissedStatus()

Constructor.

inline ~DeadlineMissedStatus()

Destructor.

Public Members

uint32_t total_count

Total cumulative number of offered deadline periods elapsed during which a writer failed to provide data.

Missed deadlines accumulate, that is, each deadline period the total_count will be incremented by 1

uint32_t total_count_change

The change in total_count since the last time the listener was called or the status was read.

InstanceHandle_t last_instance_handle

Handle to the last instance missing the deadline.

20.1.1.9.3. IncompatibleQosStatus
struct IncompatibleQosStatus

A struct storing the requested incompatible QoS status.

Public Members

uint32_t total_count = 0

Total cumulative number of times the concerned writer discovered a reader for the same topic.

The requested QoS is incompatible with the one offered by the writer

uint32_t total_count_change = 0

The change in total_count since the last time the listener was called or the status was read.

QosPolicyId_t last_policy_id = INVALID_QOS_POLICY_ID

The id of the policy that was found to be incompatible the last time an incompatibility is detected.

QosPolicyCountSeq policies

A list of QosPolicyCount.

20.1.1.9.4. InconsistentTopicStatus
using eprosima::fastdds::dds::InconsistentTopicStatus = BaseStatus

Alias of BaseStatus.

20.1.1.9.5. LivelinessChangedStatus
struct LivelinessChangedStatus

A struct storing the liveliness changed status.

Public Members

int32_t alive_count = 0

The total number of currently active publishers that write the topic read by the subscriber.

This count increases when a newly matched publisher asserts its liveliness for the first time or when a publisher previously considered to be not alive reasserts its liveliness. The count decreases when a publisher considered alive fails to assert its liveliness and becomes not alive, whether because it was deleted normally or for some other reason

int32_t not_alive_count = 0

The total count of current publishers that write the topic read by the subscriber that are no longer asserting their liveliness.

This count increases when a publisher considered alive fails to assert its liveliness and becomes not alive for some reason other than the normal deletion of that publisher. It decreases when a previously not alive publisher either reasserts its liveliness or is deleted normally

int32_t alive_count_change = 0

The change in the alive_count since the last time the listener was called or the status was read.

int32_t not_alive_count_change = 0

The change in the not_alive_count since the last time the listener was called or the status was read.

InstanceHandle_t last_publication_handle

Handle to the last publisher whose change in liveliness caused this status to change.

20.1.1.9.6. MatchedStatus
struct MatchedStatus

A structure storing a matching status.

Subclassed by eprosima::fastdds::dds::PublicationMatchedStatus, eprosima::fastdds::dds::SubscriptionMatchedStatus

Public Functions

MatchedStatus() = default

Constructor.

~MatchedStatus() = default

Destructor.

Public Members

int32_t total_count = 0

Total cumulative count the concerned reader discovered a match with a writer.

It found a writer for the same topic with a requested QoS that is compatible with that offered by the reader

int32_t total_count_change = 0

The change in total_count since the last time the listener was called or the status was read.

int32_t current_count = 0

The number of writers currently matched to the concerned reader.

int32_t current_count_change = 0

The change in current_count since the last time the listener was called or the status was read.

20.1.1.9.7. OfferedDeadlineMissedStatus
typedef DeadlineMissedStatus eprosima::fastdds::dds::OfferedDeadlineMissedStatus

Typedef of DeadlineMissedStatus.

20.1.1.9.8. OfferedIncompatibleQosStatus
using eprosima::fastdds::dds::OfferedIncompatibleQosStatus = IncompatibleQosStatus

Alias of IncompatibleQosStatus.

20.1.1.9.9. PublicationMatchedStatus
struct PublicationMatchedStatus : public eprosima::fastdds::dds::MatchedStatus

A structure storing the publication status.

Public Members

InstanceHandle_t last_subscription_handle

Handle to the last reader that matched the writer causing the status to change.

20.1.1.9.10. QosPolicyCount
struct QosPolicyCount

A struct storing the id of the incompatible QoS Policy and the number of times it fails.

Public Functions

QosPolicyCount() = default

Constructor.

inline QosPolicyCount(QosPolicyId_t id, int32_t c)

Constructor.

Public Members

QosPolicyId_t policy_id = INVALID_QOS_POLICY_ID

The id of the policy.

uint32_t count = 0

Total number of times that the concerned writer discovered a reader for the same topic.

The requested QoS is incompatible with the one offered by the writer

20.1.1.9.11. QosPolicyCountSeq
using eprosima::fastdds::dds::QosPolicyCountSeq = std::vector<QosPolicyCount>

Alias of std::vector<QosPolicyCount>

20.1.1.9.12. RequestedDeadlineMissedStatus
typedef DeadlineMissedStatus eprosima::fastdds::dds::RequestedDeadlineMissedStatus

Typedef of DeadlineMissedStatus.

20.1.1.9.13. RequestedIncompatibleQosStatus
using eprosima::fastdds::dds::RequestedIncompatibleQosStatus = IncompatibleQosStatus

Alias of IncompatibleQosStatus.

20.1.1.9.14. LivelinessLostStatus
using eprosima::fastdds::dds::LivelinessLostStatus = BaseStatus

Alias of BaseStatus.

20.1.1.9.15. SampleLostStatus
using eprosima::fastdds::dds::SampleLostStatus = BaseStatus

Alias of BaseStatus.

20.1.1.9.16. SampleRejectedStatus
struct SampleRejectedStatus

A struct storing the sample rejected status.

Public Members

uint32_t total_count = 0

Total cumulative count of samples rejected by the DataReader.

uint32_t total_count_change = 0

The incremental number of samples rejected since the last time the listener was called or the status was read.

SampleRejectedStatusKind last_reason = NOT_REJECTED

Reason for rejecting the last sample rejected. If no samples have been rejected, the reason is the special value NOT_REJECTED.

InstanceHandle_t last_instance_handle

Handle to the instance being updated by the last sample that was rejected.

20.1.1.9.17. SampleRejectedStatusKind
enum eprosima::fastdds::dds::SampleRejectedStatusKind

An enum with the possible values for the sample rejected reason.

Values:

enumerator NOT_REJECTED

Default value.

enumerator REJECTED_BY_INSTANCES_LIMIT

Exceeds the max_instance limit.

enumerator REJECTED_BY_SAMPLES_LIMIT

Exceeds the max_samples limit.

enumerator REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT

Exceeds the max_samples_per_instance limit.

20.1.1.9.18. StatusMask
class StatusMask : public std::bitset<FASTDDS_STATUS_COUNT>

StatusMask is a bitmap or bitset field.

This bitset is used to:

  • determine which listener functions to call

  • set conditions in dds::core::cond::StatusCondition

  • indicate status changes when calling dds::core::Entity::status_changes

Public Types

typedef std::bitset<FASTDDS_STATUS_COUNT> MaskType

Convenience typedef for std::bitset<FASTDDS_STATUS_COUNT>.

Public Functions

inline StatusMask()

Construct an StatusMask with no flags set.

inline explicit StatusMask(uint32_t mask)

Construct an StatusMask with an uint32_t bit mask.

Parameters:

mask – the bit array to initialize the bitset with

inline StatusMask &operator<<(const StatusMask &mask)

Add given StatusMask bits into this StatusMask bitset.

Returns:

StatusMask this

inline StatusMask &operator>>(const StatusMask &mask)

Remove given StatusMask bits into this StatusMask bitset.

Returns:

StatusMask this

inline bool is_active(StatusMask status) const

Checks if the status passed as parameter is 1 in the actual StatusMask.

Parameters:

status – Status that need to be checked

Returns:

true if the status is active and false if not

Public Static Functions

static inline StatusMask all()

Get all StatusMasks

Returns:

StatusMask all

static inline StatusMask none()

Get no StatusMasks

Returns:

StatusMask none

static inline StatusMask inconsistent_topic()

Get the StatusMask associated with dds::core::status::InconsistentTopicStatus

Returns:

StatusMask inconsistent_topic

static inline StatusMask offered_deadline_missed()

Get the StatusMask associated with dds::core::status::OfferedDeadlineMissedStatus

Returns:

StatusMask offered_deadline_missed

static inline StatusMask requested_deadline_missed()

Get the StatusMask associated with dds::core::status::RequestedDeadlineMissedStatus

Returns:

StatusMask requested_deadline_missed

static inline StatusMask offered_incompatible_qos()

Get the StatusMask associated with dds::core::status::OfferedIncompatibleQosStatus

Returns:

StatusMask offered_incompatible_qos

static inline StatusMask requested_incompatible_qos()

Get the StatusMask associated with dds::core::status::RequestedIncompatibleQosStatus

Returns:

StatusMask requested_incompatible_qos

static inline StatusMask sample_lost()

Get the StatusMask associated with dds::core::status::SampleLostStatus

Returns:

StatusMask sample_lost

static inline StatusMask sample_rejected()

Get the StatusMask associated with dds::core::status::SampleRejectedStatus

Returns:

StatusMask sample_rejected

static inline StatusMask data_on_readers()

Get the StatusMask associated with dds::core::status::data_on_readers

Returns:

StatusMask data_on_readers

static inline StatusMask data_available()

get the statusmask associated with dds::core::status::data_available

Returns:

statusmask data_available

static inline StatusMask liveliness_lost()

Get the StatusMask associated with dds::core::status::LivelinessLostStatus

Returns:

StatusMask liveliness_lost

static inline StatusMask liveliness_changed()

Get the StatusMask associated with dds::core::status::LivelinessChangedStatus

Returns:

StatusMask liveliness_changed

static inline StatusMask publication_matched()

Get the statusmask associated with dds::core::status::PublicationMatchedStatus

Returns:

StatusMask publication_matched

static inline StatusMask subscription_matched()

Get the statusmask associated with dds::core::status::SubscriptionMatchedStatus

Returns:

StatusMask subscription_matched

FASTDDS_STATUS_COUNT size_t(16)

Alias of size_t(16)

20.1.1.9.19. SubscriptionMatchedStatus
struct SubscriptionMatchedStatus : public eprosima::fastdds::dds::MatchedStatus

A structure storing the subscription status.

Public Members

InstanceHandle_t last_publication_handle

Handle to the last writer that matched the reader causing the status change.

20.1.1.10. DDS Time_t
20.1.1.10.1. Const values
const Time_t eprosima::fastdds::dds::c_TimeInfinite = {Time_t::INFINITE_SECONDS, Time_t::INFINITE_NANOSECONDS}

Time_t (dds::Duration_t) representing an infinite time. DONT USE IT IN CONSTRUCTORS.

const Time_t eprosima::fastdds::dds::c_TimeZero = {0, 0}

Time_t (dds::Duration_t) representing a zero time. DONT USE IT IN CONSTRUCTORS.

const Time_t eprosima::fastdds::dds::c_TimeInvalid = {-1, Time_t::INFINITE_NANOSECONDS}

Time_t (dds::Duration_t) representing an invalid time. DONT USE IT IN CONSTRUCTORS.

20.1.1.10.2. DDS Layer Duration_t
using eprosima::fastdds::dds::Duration_t = Time_t
20.1.1.10.3. Time_t DDS Operators
static inline bool eprosima::fastdds::dds::operator==(const Time_t &t1, const Time_t &t2)

Comparison assignment

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if equal

static inline bool eprosima::fastdds::dds::operator!=(const Time_t &t1, const Time_t &t2)

Comparison assignment

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if not equal

static inline bool eprosima::fastdds::dds::operator<(const Time_t &t1, const Time_t &t2)

Checks if a Time_t is less than other.

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if the first Time_t is less than the second

static inline bool eprosima::fastdds::dds::operator>(const Time_t &t1, const Time_t &t2)

Checks if a Time_t is greater than other.

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if the first Time_t is greater than the second

static inline bool eprosima::fastdds::dds::operator<=(const Time_t &t1, const Time_t &t2)

Checks if a Time_t is less or equal than other.

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if the first Time_t is less or equal than the second

static inline bool eprosima::fastdds::dds::operator>=(const Time_t &t1, const Time_t &t2)

Checks if a Time_t is greater or equal than other.

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if the first Time_t is greater or equal than the second

inline std::ostream &eprosima::fastdds::dds::operator<<(std::ostream &output, const Time_t &t)
static inline Time_t eprosima::fastdds::dds::operator+(const Time_t &ta, const Time_t &tb)

Adds two Time_t.

Parameters:
Returns:

A new Time_t with the result.

static inline Time_t eprosima::fastdds::dds::operator-(const Time_t &ta, const Time_t &tb)

Subtracts two Time_t.

Parameters:
  • ta – First Time_t to subtract

  • tb – Second Time_t to subtract

Returns:

A new Time_t with the result.

20.1.1.10.4. DDS Layer Time_t
struct Time_t

Structure Time_t, used to describe times at a DDS level.

Public Functions

Time_t()

Default constructor. Sets values to zero.

Time_t(int32_t sec, uint32_t nsec)
Parameters:
  • sec – Seconds

  • nsec – Nanoseconds

Time_t(long double sec)
Parameters:

sec – Seconds. The fractional part is converted to nanoseconds.

int64_t to_ns() const

Returns stored time as nanoseconds (including seconds)

Public Static Functions

static void now(Time_t &ret)

Fills a Time_t struct with a representation of the current time.

Parameters:

ret – Reference to the structure to be filled in.

20.1.2. Domain

20.1.2.1. DomainParticipant
class DomainParticipant : public eprosima::fastdds::dds::Entity

Class DomainParticipant used to group Publishers and Subscribers into a single working unit.

Subclassed by eprosima::fastdds::statistics::dds::DomainParticipant

Public Functions

virtual ~DomainParticipant()

Destructor.

ReturnCode_t get_qos(DomainParticipantQos &qos) const

This operation returns the value of the DomainParticipant QoS policies

Parameters:

qosDomainParticipantQos reference where the qos is going to be returned

Returns:

RETCODE_OK

const DomainParticipantQos &get_qos() const

This operation returns the value of the DomainParticipant QoS policies.

Returns:

A reference to the DomainParticipantQos

ReturnCode_t set_qos(const DomainParticipantQos &qos) const

This operation sets the value of the DomainParticipant QoS policies.

Parameters:

qosDomainParticipantQos to be set

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const DomainParticipantListener *get_listener() const

Allows accessing the DomainParticipantListener.

Returns:

DomainParticipantListener pointer

ReturnCode_t set_listener(DomainParticipantListener *listener)

Modifies the DomainParticipantListener, sets the mask to StatusMask::all()

Warning

Do not call this method from a DomainParticipantListener callback.

Parameters:

listener – New value for the DomainParticipantListener

Returns:

RETCODE_OK if successful, RETCODE_ERROR otherwise.

ReturnCode_t set_listener(DomainParticipantListener *listener, const std::chrono::seconds timeout)

Modifies the DomainParticipantListener, sets the mask to StatusMask::all()

Warning

Do not call this method from a DomainParticipantListener callback.

Parameters:
  • listener – New value for the DomainParticipantListener

  • timeout – Maximum time to wait for executing callbacks to finish.

Returns:

RETCODE_OK if successful, RETCODE_ERROR if failed (timeout expired).

ReturnCode_t set_listener(DomainParticipantListener *listener, const StatusMask &mask)

Modifies the DomainParticipantListener.

Warning

Do not call this method from a DomainParticipantListener callback.

Parameters:
Returns:

RETCODE_OK if successful, RETCODE_ERROR otherwise.

ReturnCode_t set_listener(DomainParticipantListener *listener, const StatusMask &mask, const std::chrono::seconds timeout)

Modifies the DomainParticipantListener.

Warning

Do not call this method from a DomainParticipantListener callback.

Parameters:
  • listener – New value for the DomainParticipantListener

  • maskStatusMask that holds statuses the listener responds to

  • timeout – Maximum time to wait for executing callbacks to finish.

Returns:

RETCODE_OK if successful, RETCODE_ERROR if failed (timeout expired)

virtual ReturnCode_t enable() override

This operation enables the DomainParticipant.

Returns:

RETCODE_OK

Publisher *create_publisher(const PublisherQos &qos, PublisherListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Publisher in this Participant.

Parameters:
  • qos – QoS of the Publisher.

  • listener – Pointer to the listener (default: nullptr)

  • maskStatusMask that holds statuses the listener responds to (default: all)

Returns:

Pointer to the created Publisher.

Publisher *create_publisher_with_profile(const std::string &profile_name, PublisherListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Publisher in this Participant.

Parameters:
  • profile_namePublisher profile name.

  • listener – Pointer to the listener (default: nullptr)

  • maskStatusMask that holds statuses the listener responds to (default: all)

Returns:

Pointer to the created Publisher.

ReturnCode_t delete_publisher(const Publisher *publisher)

Deletes an existing Publisher.

Parameters:

publisher – to be deleted.

Returns:

RETCODE_PRECONDITION_NOT_MET if the publisher does not belong to this participant or if it has active DataWriters, RETCODE_OK if it is correctly deleted and RETCODE_ERROR otherwise.

Subscriber *create_subscriber(const SubscriberQos &qos, SubscriberListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Subscriber in this Participant.

Parameters:
  • qos – QoS of the Subscriber.

  • listener – Pointer to the listener (default: nullptr)

  • maskStatusMask that holds statuses the listener responds to (default: all)

Returns:

Pointer to the created Subscriber.

Subscriber *create_subscriber_with_profile(const std::string &profile_name, SubscriberListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Subscriber in this Participant.

Parameters:
  • profile_nameSubscriber profile name.

  • listener – Pointer to the listener (default: nullptr)

  • maskStatusMask that holds statuses the listener responds to (default: all)

Returns:

Pointer to the created Subscriber.

ReturnCode_t delete_subscriber(const Subscriber *subscriber)

Deletes an existing Subscriber.

Parameters:

subscriber – to be deleted.

Returns:

RETCODE_PRECONDITION_NOT_MET if the subscriber does not belong to this participant or if it has active DataReaders, RETCODE_OK if it is correctly deleted and RETCODE_ERROR otherwise.

Topic *create_topic(const std::string &topic_name, const std::string &type_name, const TopicQos &qos, TopicListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Topic in this Participant.

Parameters:
  • topic_name – Name of the Topic.

  • type_name – Data type of the Topic.

  • qos – QoS of the Topic.

  • listener – Pointer to the listener (default: nullptr)

  • maskStatusMask that holds statuses the listener responds to (default: all)

Returns:

Pointer to the created Topic.

Topic *create_topic_with_profile(const std::string &topic_name, const std::string &type_name, const std::string &profile_name, TopicListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Topic in this Participant.

Parameters:
  • topic_name – Name of the Topic.

  • type_name – Data type of the Topic.

  • profile_nameTopic profile name.

  • listener – Pointer to the listener (default: nullptr)

  • maskStatusMask that holds statuses the listener responds to (default: all)

Returns:

Pointer to the created Topic.

ReturnCode_t delete_topic(const Topic *topic)

Deletes an existing Topic.

Parameters:

topic – to be deleted.

Returns:

RETCODE_BAD_PARAMETER if the topic passed is a nullptr, RETCODE_PRECONDITION_NOT_MET if the topic does not belong to this participant or if it is referenced by any entity and RETCODE_OK if the Topic was deleted.

ContentFilteredTopic *create_contentfilteredtopic(const std::string &name, Topic *related_topic, const std::string &filter_expression, const std::vector<std::string> &expression_parameters)

Create a ContentFilteredTopic in this Participant.

Parameters:
  • name – Name of the ContentFilteredTopic

  • related_topic – Related Topic to being subscribed

  • filter_expression – Logic expression to create filter

  • expression_parameters – Parameters to filter content

Returns:

Pointer to the created ContentFilteredTopic.

Returns:

nullptr if related_topic does not belong to this participant.

Returns:

nullptr if a topic with the specified name has already been created.

Returns:

nullptr if a filter cannot be created with the specified filter_expression and expression_parameters.

ContentFilteredTopic *create_contentfilteredtopic(const std::string &name, Topic *related_topic, const std::string &filter_expression, const std::vector<std::string> &expression_parameters, const char *filter_class_name)

Create a ContentFilteredTopic in this Participant using a custom filter.

Parameters:
  • name – Name of the ContentFilteredTopic

  • related_topic – Related Topic to being subscribed

  • filter_expression – Logic expression to create filter

  • expression_parameters – Parameters to filter content

  • filter_class_name – Name of the filter class to use

Returns:

Pointer to the created ContentFilteredTopic.

Returns:

nullptr if related_topic does not belong to this participant.

Returns:

nullptr if a topic with the specified name has already been created.

Returns:

nullptr if a filter cannot be created with the specified filter_expression and expression_parameters.

Returns:

nullptr if the specified filter_class_name has not been registered.

ReturnCode_t delete_contentfilteredtopic(const ContentFilteredTopic *a_contentfilteredtopic)

Deletes an existing ContentFilteredTopic.

Parameters:

a_contentfilteredtopicContentFilteredTopic to be deleted

Returns:

RETCODE_BAD_PARAMETER if the topic passed is a nullptr, RETCODE_PRECONDITION_NOT_MET if the topic does not belong to this participant or if it is referenced by any entity and RETCODE_OK if the ContentFilteredTopic was deleted.

MultiTopic *create_multitopic(const std::string &name, const std::string &type_name, const std::string &subscription_expression, const std::vector<std::string> &expression_parameters)

Create a MultiTopic in this Participant.

Parameters:
  • name – Name of the MultiTopic

  • type_name – Result type of the MultiTopic

  • subscription_expression – Logic expression to combine filter

  • expression_parameters – Parameters to subscription content

Returns:

Pointer to the created ContentFilteredTopic, nullptr in error case

ReturnCode_t delete_multitopic(const MultiTopic *a_multitopic)

Deletes an existing MultiTopic.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

a_multitopic – MultiTopic to be deleted

Returns:

RETCODE_BAD_PARAMETER if the topic passed is a nullptr, RETCODE_PRECONDITION_NOT_MET if the topic does not belong to this participant or if it is referenced by any entity and RETCODE_OK if the Topic was deleted.

Topic *find_topic(const std::string &topic_name, const fastdds::dds::Duration_t &timeout)

Gives access to an existing (or ready to exist) enabled Topic. It should be noted that the returned Topic is a local object that acts as a proxy to designate the global concept of topic. Topics obtained by means of find_topic, must also be deleted by means of delete_topic so that the local resources can be released. If a Topic is obtained multiple times by means of find_topic or create_topic, it must also be deleted that same number of times using delete_topic.

Parameters:
  • topic_nameTopic name

  • timeout – Maximum time to wait for the Topic

Returns:

Pointer to the existing Topic, nullptr in case of error or timeout

rpc::Service *create_service(const std::string &service_name, const std::string &service_type_name)

Create a RPC service.

Parameters:
  • service_name – Name of the service.

  • service_type_name – Type name of the service (Request & reply types)

Returns:

Pointer to the created service. nullptr in error case.

rpc::Service *find_service(const std::string &service_name) const

Find a RPC service by name

Parameters:

service_name – Name of the service to search for.

Returns:

Pointer to the service object if found, nullptr if not found.

ReturnCode_t delete_service(const rpc::Service *service)

Delete a registered RPC service

Parameters:

service – Pointer to the service to be deleted.

Returns:

RETCODE_OK if the service was deleted, or an specific error code otherwise.

rpc::Requester *create_service_requester(rpc::Service *service, const RequesterQos &requester_qos)

Create a RPC Requester in a given Service.

Parameters:
  • service – Pointer to a service object where the requester will be created.

  • requester_qos – QoS of the requester.

Returns:

Pointer to the created requester. nullptr in error case.

ReturnCode_t delete_service_requester(const std::string &service_name, rpc::Requester *requester)

Deletes an existing RPC Requester

Parameters:
  • service_name – Name of the service where the requester is created.

  • requester – Pointer to the requester to be deleted.

Returns:

RETCODE_OK if the requester was deleted, or an specific error code otherwise.

rpc::Replier *create_service_replier(rpc::Service *service, const ReplierQos &replier_qos)

Create a RPC Replier in a given Service. It will override the current service’s replier

Parameters:
  • service – Pointer to a service object where the Replier will be created.

  • replier_qos – QoS of the replier.

Returns:

Pointer to the created replier. nullptr in error case.

ReturnCode_t delete_service_replier(const std::string &service_name, rpc::Replier *replier)

Deletes an existing RPC Replier

Parameters:
  • service_name – Name of the service where the replier is created.

  • replier – Pointer to the replier to be deleted.

Returns:

RETCODE_OK if the replier was deleted, or an specific error code otherwise.

TopicDescription *lookup_topicdescription(const std::string &topic_name) const

Looks up an existing, locally created TopicDescription, based on its name. May be called on a disabled participant.

Remark

UNSAFE. It is unsafe to lookup a topic description while another thread is creating a topic.

Parameters:

topic_name – Name of the TopicDescription to search for.

Returns:

Pointer to the topic description, if it has been created locally. Otherwise, nullptr is returned.

const Subscriber *get_builtin_subscriber() const

Allows access to the builtin Subscriber.

Returns:

Pointer to the builtin Subscriber, nullptr in error case

ReturnCode_t ignore_participant(const InstanceHandle_t &handle)

Locally ignore a remote domain participant.

Note

This action is not reversible.

Parameters:

handle – Identifier of the remote participant to ignore

Returns:

RETURN_OK code if everything correct, RETCODE_BAD_PARAMENTER otherwise

ReturnCode_t ignore_topic(const InstanceHandle_t &handle)

Locally ignore a topic.

Note

This action is not reversible.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

handle – Identifier of the topic to ignore

Returns:

RETURN_OK code if everything correct, error code otherwise

ReturnCode_t ignore_publication(const InstanceHandle_t &handle)

Locally ignore a remote datawriter.

Note

This action is not reversible.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

handle – Identifier of the datawriter to ignore

Returns:

RETURN_OK code if everything correct, error code otherwise

ReturnCode_t ignore_subscription(const InstanceHandle_t &handle)

Locally ignore a remote datareader.

Note

This action is not reversible.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

handle – Identifier of the datareader to ignore

Returns:

RETURN_OK code if everything correct, error code otherwise

DomainId_t get_domain_id() const

This operation retrieves the domain_id used to create the DomainParticipant. The domain_id identifies the DDS domain to which the DomainParticipant belongs.

Returns:

The Participant’s domain_id

ReturnCode_t delete_contained_entities()

Deletes all the entities that were created by means of the “create” methods

Returns:

RETURN_OK code if everything correct, error code otherwise

ReturnCode_t assert_liveliness()

This operation manually asserts the liveliness of the DomainParticipant. This is used in combination with the LIVELINESS QoS policy to indicate to the Service that the entity remains active.

This operation needs to only be used if the DomainParticipant contains DataWriter entities with the LIVELINESS set to MANUAL_BY_PARTICIPANT and it only affects the liveliness of those DataWriter entities. Otherwise, it has no effect.

Note

Writing data via the write operation on a DataWriter asserts liveliness on the DataWriter itself and its DomainParticipant. Consequently the use of assert_liveliness is only needed if the application is not writing data regularly.

Returns:

RETCODE_OK if the liveliness was asserted, RETCODE_ERROR otherwise.

ReturnCode_t set_default_publisher_qos(const PublisherQos &qos)

This operation sets a default value of the Publisher QoS policies which will be used for newly created Publisher entities in the case where the QoS policies are defaulted in the create_publisher operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return false.

The special value PUBLISHER_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_publisher_qos operation had never been called.

Parameters:

qosPublisherQos to be set

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const PublisherQos &get_default_publisher_qos() const

This operation retrieves the default value of the Publisher QoS, that is, the QoS policies which will be used for newly created Publisher entities in the case where the QoS policies are defaulted in the create_publisher operation.

The values retrieved get_default_publisher_qos will match the set of values specified on the last successful call to set_default_publisher_qos, or else, if the call was never made, the default values.

Returns:

Current default publisher qos.

ReturnCode_t get_default_publisher_qos(PublisherQos &qos) const

This operation retrieves the default value of the Publisher QoS, that is, the QoS policies which will be used for newly created Publisher entities in the case where the QoS policies are defaulted in the create_publisher operation.

The values retrieved get_default_publisher_qos will match the set of values specified on the last successful call to set_default_publisher_qos, or else, if the call was never made, the default values.

Parameters:

qosPublisherQos reference where the default_publisher_qos is returned

Returns:

RETCODE_OK

ReturnCode_t get_publisher_qos_from_profile(const std::string &profile_name, PublisherQos &qos) const

Fills the PublisherQos with the values of the XML profile.

Parameters:
Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_publisher_qos_from_xml(const std::string &xml, PublisherQos &qos) const

Fills the PublisherQos with the first publisher profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosPublisherQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_publisher_qos_from_xml(const std::string &xml, PublisherQos &qos, const std::string &profile_name) const

Fills the PublisherQos with the publisher profile with profile_name to be found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosPublisherQos object where the qos is returned.

  • profile_namePublisher profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_publisher_qos_from_xml(const std::string &xml, PublisherQos &qos) const

Fills the PublisherQos with the default publisher profile found in the provided XML (if there is).

Note

This method does not update the default publisher qos (returned by get_default_publisher_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosPublisherQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t set_default_subscriber_qos(const SubscriberQos &qos)

This operation sets a default value of the Subscriber QoS policies that will be used for newly created Subscriber entities in the case where the QoS policies are defaulted in the create_subscriber operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return false.

The special value SUBSCRIBER_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_subscriber_qos operation had never been called.

Parameters:

qosSubscriberQos to be set

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const SubscriberQos &get_default_subscriber_qos() const

This operation retrieves the default value of the Subscriber QoS, that is, the QoS policies which will be used for newly created Subscriber entities in the case where the QoS policies are defaulted in the create_subscriber operation.

The values retrieved get_default_subscriber_qos will match the set of values specified on the last successful call to set_default_subscriber_qos, or else, if the call was never made, the default values.

Returns:

Current default subscriber qos.

ReturnCode_t get_default_subscriber_qos(SubscriberQos &qos) const

This operation retrieves the default value of the Subscriber QoS, that is, the QoS policies which will be used for newly created Subscriber entities in the case where the QoS policies are defaulted in the create_subscriber operation.

The values retrieved get_default_subscriber_qos will match the set of values specified on the last successful call to set_default_subscriber_qos, or else, if the call was never made, the default values.

Parameters:

qosSubscriberQos reference where the default_subscriber_qos is returned

Returns:

RETCODE_OK

ReturnCode_t get_subscriber_qos_from_profile(const std::string &profile_name, SubscriberQos &qos) const

Fills the SubscriberQos with the values of the XML profile.

Parameters:
Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_subscriber_qos_from_xml(const std::string &xml, SubscriberQos &qos) const

Fills the SubscriberQos with the first subscriber profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosSubscriberQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_subscriber_qos_from_xml(const std::string &xml, SubscriberQos &qos, const std::string &profile_name) const

Fills the SubscriberQos with the subscriber profile with profile_name to be found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosSubscriberQos object where the qos is returned.

  • profile_nameSubscriber profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_subscriber_qos_from_xml(const std::string &xml, SubscriberQos &qos) const

Fills the SubscriberQos with the default subscriber profile found in the provided XML (if there is).

Note

This method does not update the default subscriber qos (returned by get_default_subscriber_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosSubscriberQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t set_default_topic_qos(const TopicQos &qos)

This operation sets a default value of the Topic QoS policies which will be used for newly created Topic entities in the case where the QoS policies are defaulted in the create_topic operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return INCONSISTENT_POLICY.

The special value TOPIC_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_topic_qos operation had never been called.

Parameters:

qosTopicQos to be set

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const TopicQos &get_default_topic_qos() const

This operation retrieves the default value of the Topic QoS, that is, the QoS policies that will be used for newly created Topic entities in the case where the QoS policies are defaulted in the create_topic operation.

The values retrieved get_default_topic_qos will match the set of values specified on the last successful call to set_default_topic_qos, or else, TOPIC_QOS_DEFAULT if the call was never made.

Returns:

Current default topic qos.

ReturnCode_t get_default_topic_qos(TopicQos &qos) const

This operation retrieves the default value of the Topic QoS, that is, the QoS policies that will be used for newly created Topic entities in the case where the QoS policies are defaulted in the create_topic operation.

The values retrieved get_default_topic_qos will match the set of values specified on the last successful call to set_default_topic_qos, or else, TOPIC_QOS_DEFAULT if the call was never made.

Parameters:

qosTopicQos reference where the default_topic_qos is returned

Returns:

RETCODE_OK

ReturnCode_t get_topic_qos_from_profile(const std::string &profile_name, TopicQos &qos) const

Fills the TopicQos with the values of the XML profile.

Parameters:
  • profile_nameTopic profile name.

  • qosTopicQos object where the qos is returned.

Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_topic_qos_from_profile(const std::string &profile_name, TopicQos &qos, std::string &topic_name, std::string &topic_data_type) const

Fills the TopicQos with the values of the XML profile, and also its corresponding topic and data type names (if specified).

Parameters:
  • profile_nameTopic profile name.

  • qosTopicQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

  • topic_data_type – String where the name of the topic data type associated to this profile is returned (if specified).

Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_topic_qos_from_xml(const std::string &xml, TopicQos &qos) const

Fills the TopicQos with the first topic profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosTopicQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_topic_qos_from_xml(const std::string &xml, TopicQos &qos, std::string &topic_name, std::string &topic_data_type) const

Fills the TopicQos with the first topic profile found in the provided XML, and also its corresponding topic and data type names (if specified).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosTopicQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

  • topic_data_type – String where the name of the topic data type associated to this profile is returned (if specified).

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_topic_qos_from_xml(const std::string &xml, TopicQos &qos, const std::string &profile_name) const

Fills the TopicQos with the topic profile with profile_name to be found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosTopicQos object where the qos is returned.

  • profile_nameTopic profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_topic_qos_from_xml(const std::string &xml, TopicQos &qos, std::string &topic_name, std::string &topic_data_type, const std::string &profile_name) const

Fills the TopicQos with the topic profile with profile_name to be found in the provided XML, and also its corresponding topic and data type names (if specified).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosTopicQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

  • topic_data_type – String where the name of the topic data type associated to this profile is returned (if specified).

  • profile_nameTopic profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_topic_qos_from_xml(const std::string &xml, TopicQos &qos) const

Fills the TopicQos with the default topic profile found in the provided XML (if there is).

Note

This method does not update the default topic qos (returned by get_default_topic_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosTopicQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_topic_qos_from_xml(const std::string &xml, TopicQos &qos, std::string &topic_name, std::string &topic_data_type) const

Fills the TopicQos with the default topic profile found in the provided XML (if there is), and also its corresponding topic and data type names (if specified).

Note

This method does not update the default topic qos (returned by get_default_topic_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosTopicQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

  • topic_data_type – String where the name of the topic data type associated to this profile is returned (if specified).

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_replier_qos_from_profile(const std::string &profile_name, ReplierQos &qos) const

Fills the ReplierQos with the values of the XML profile.

Parameters:
  • profile_name – Replier profile name.

  • qosReplierQos object where the qos is returned.

Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_replier_qos_from_xml(const std::string &xml, ReplierQos &qos) const

Fills the ReplierQos with the first replier profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosReplierQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_replier_qos_from_xml(const std::string &xml, ReplierQos &qos, const std::string &profile_name) const

Fills the ReplierQos with the replier profile with profile_name to be found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosReplierQos object where the qos is returned.

  • profile_name – Replier profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_replier_qos_from_xml(const std::string &xml, ReplierQos &qos) const

Fills the ReplierQos with the default replier profile found in the provided XML (if there is).

Note

This method does not update the default replier qos.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosReplierQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_requester_qos_from_profile(const std::string &profile_name, RequesterQos &qos) const

Fills the RequesterQos with the values of the XML profile.

Parameters:
  • profile_name – Requester profile name.

  • qosRequesterQos object where the qos is returned.

Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_requester_qos_from_xml(const std::string &xml, RequesterQos &qos) const

Fills the RequesterQos with the first requester profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosRequesterQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_requester_qos_from_xml(const std::string &xml, RequesterQos &qos, const std::string &profile_name) const

Fills the RequesterQos with the requester profile with profile_name to be found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosRequesterQos object where the qos is returned.

  • profile_name – Requester profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_requester_qos_from_xml(const std::string &xml, RequesterQos &qos) const

Fills the RequesterQos with the default requester profile found in the provided XML (if there is).

Note

This method does not update the default requester qos.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosRequesterQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_discovered_participants(std::vector<InstanceHandle_t> &participant_handles) const

Retrieves the list of DomainParticipants that have been discovered in the domain and are not “ignored”.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

participant_handles[out] Reference to the vector where discovered participants will be returned

Returns:

RETCODE_OK if everything correct, error code otherwise

ReturnCode_t get_discovered_participant_data(ParticipantBuiltinTopicData &participant_data, const InstanceHandle_t &participant_handle) const

Retrieves the DomainParticipant data of a discovered not ignored participant.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:
  • participant_data[out] Reference to the ParticipantBuiltinTopicData object to return the data

  • participant_handle – InstanceHandle of DomainParticipant to retrieve the data from

Returns:

RETCODE_OK if everything correct, PRECONDITION_NOT_MET if participant does not exist

ReturnCode_t get_discovered_topics(std::vector<InstanceHandle_t> &topic_handles) const

Retrieves the list of topics that have been discovered in the domain and are not “ignored”.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

topic_handles[out] Reference to the vector where discovered topics will be returned

Returns:

RETCODE_OK if everything correct, error code otherwise

ReturnCode_t get_discovered_topic_data(builtin::TopicBuiltinTopicData &topic_data, const InstanceHandle_t &topic_handle) const

Retrieves the Topic data of a discovered not ignored topic.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:
  • topic_data[out] Reference to the TopicBuiltinTopicData object to return the data

  • topic_handle – InstanceHandle of Topic to retrieve the data from

Returns:

RETCODE_OK if everything correct, PRECONDITION_NOT_MET if topic does not exist

bool contains_entity(const InstanceHandle_t &a_handle, bool recursive = true) const

This operation checks whether or not the given handle represents an Entity that was created from the DomainParticipant.

Parameters:
Returns:

True if entity is contained. False otherwise.

ReturnCode_t get_current_time(fastdds::dds::Time_t &current_time) const

This operation returns the current value of the time that the service uses to time-stamp data-writes and to set the reception-timestamp for the data-updates it receives.

Parameters:

current_timeTime_t reference where the current time is returned

Returns:

RETCODE_OK

ReturnCode_t register_type(TypeSupport type, const std::string &type_name)

Register a type in this participant.

Parameters:
  • typeTypeSupport.

  • type_name – The name that will be used to identify the Type.

Returns:

RETCODE_BAD_PARAMETER if the size of the name is 0, RERCODE_PRECONDITION_NOT_MET if there is another TypeSupport with the same name and RETCODE_OK if it is correctly registered.

ReturnCode_t register_type(TypeSupport type)

Register a type in this participant.

Parameters:

typeTypeSupport.

Returns:

RETCODE_BAD_PARAMETER if the size of the name is 0, RERCODE_PRECONDITION_NOT_MET if there is another TypeSupport with the same name and RETCODE_OK if it is correctly registered.

ReturnCode_t unregister_type(const std::string &typeName)

Unregister a type in this participant.

Parameters:

typeName – Name of the type

Returns:

RETCODE_BAD_PARAMETER if the size of the name is 0, RERCODE_PRECONDITION_NOT_MET if there are entities using that TypeSupport and RETCODE_OK if it is correctly unregistered.

TypeSupport find_type(const std::string &type_name) const

This method gives access to a registered type based on its name.

Parameters:

type_name – Name of the type

Returns:

TypeSupport corresponding to the type_name

ReturnCode_t register_service_type(rpc::ServiceTypeSupport service_type, const std::string &service_type_name)

Register a service type in this participant.

Parameters:
  • service_type – ServiceTypeSupport.

  • service_type_name – The name that will be used to identify the service type.

Returns:

RETCODE_OK if it is correctly registered. Error code otherwise.

ReturnCode_t unregister_service_type(const std::string &service_type_name)

Unregister a service type in this participant.

Parameters:

service_type_name – Name of the type

Returns:

RETCODE_OK if it is correctly unregistered. Error code otherwise.

rpc::ServiceTypeSupport find_service_type(const std::string &service_type_name) const

This method gives access to a registered service type based on its name.

Parameters:

service_type_name – Name of the type

Returns:

ServiceTypeSupport corresponding to the service_type_name

const InstanceHandle_t &get_instance_handle() const

Returns the DomainParticipant’s handle.

Returns:

InstanceHandle of this DomainParticipant.

const fastdds::rtps::GUID_t &guid() const

Getter for the Participant GUID.

Returns:

A reference to the GUID

std::vector<std::string> get_participant_names() const

Getter for the participant names.

Returns:

Vector with the names

bool new_remote_endpoint_discovered(const fastdds::rtps::GUID_t &partguid, uint16_t userId, fastdds::rtps::EndpointKind_t kind)

This method can be used when using a StaticEndpointDiscovery mechanism different that the one included in Fast DDS, for example when communicating with other implementations. It indicates the Participant that an Endpoint from the XML has been discovered and should be activated.

Parameters:
  • partguid – Participant GUID_t.

  • userId – User defined ID as shown in the XML file.

  • kind – EndpointKind (WRITER or READER)

Returns:

True if correctly found and activated.

ReturnCode_t register_content_filter_factory(const char *filter_class_name, IContentFilterFactory *const filter_factory)

Register a custom content filter factory, which can be used to create a ContentFilteredTopic.

DDS specifies a SQL-like content filter to be used by content filtered topics. If this filter does not meet your filtering requirements, you can register a custom filter factory.

To use a custom filter, a factory for it must be registered in the following places:

  • In any application that uses the custom filter factory to create a ContentFilteredTopic and the corresponding DataReader.

  • In each application that writes the data to the applications mentioned above.

For example, suppose Application A on the subscription side creates a Topic named X and a ContentFilteredTopic named filteredX (and a corresponding DataReader), using a previously registered content filter factory, myFilterFactory. With only that, you will have filtering at the subscription side. If you also want to perform filtering in any application that publishes Topic X, then you also need to register the same definition of the ContentFilterFactory myFilterFactory in that application.

Each filter_class_name can only be used to register a content filter factory once per DomainParticipant.

Parameters:
  • filter_class_name – Name of the filter class. Cannot be nullptr, must not exceed 255 characters, and must be unique within this DomainParticipant.

  • filter_factory – Factory of content filters to be registered. Cannot be nullptr.

Returns:

RETCODE_BAD_PARAMETER if any parameter is nullptr, or the filter_class_name exceeds 255 characters.

Returns:

RETCODE_PRECONDITION_NOT_MET if the filter_class_name has been already registered.

Returns:

RETCODE_PRECONDITION_NOT_MET if filter_class_name is FASTDDS_SQLFILTER_NAME.

Returns:

RETCODE_OK if the filter is correctly registered.

IContentFilterFactory *lookup_content_filter_factory(const char *filter_class_name)

Lookup a custom content filter factory previously registered with register_content_filter_factory.

Parameters:

filter_class_name – Name of the filter class. Cannot be nullptr.

Returns:

nullptr if the given filter_class_name has not been previously registered on this DomainParticipant. Otherwise, the content filter factory previously registered with the given filter_class_name.

ReturnCode_t unregister_content_filter_factory(const char *filter_class_name)

Unregister a custom content filter factory previously registered with register_content_filter_factory.

A filter_class_name can be unregistered only if it has been previously registered to the DomainParticipant with register_content_filter_factory.

The unregistration of filter is not allowed if there are any existing ContentFilteredTopic objects that are using the filter.

If there is any existing discovered DataReader with the same filter_class_name, filtering on the writer side will be stopped, but this operation will not fail.

Parameters:

filter_class_name – Name of the filter class. Cannot be nullptr.

Returns:

RETCODE_BAD_PARAMETER if the filter_class_name is nullptr.

Returns:

RERCODE_PRECONDITION_NOT_MET if the filter_class_name has not been previously registered.

Returns:

RERCODE_PRECONDITION_NOT_MET if there is any ContentFilteredTopic referencing the filter.

Returns:

RETCODE_OK if the filter is correctly unregistered.

bool has_active_entities()

Check if the Participant has any Publisher, Subscriber or Topic.

Returns:

true if any, false otherwise.

20.1.2.2. DomainParticipantFactory
class DomainParticipantFactory

Class DomainParticipantFactory

Public Functions

DomainParticipant *create_participant(DomainId_t domain_id, const DomainParticipantQos &qos, DomainParticipantListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Participant.

Parameters:
Returns:

DomainParticipant pointer. (nullptr if not created.)

DomainParticipant *create_participant(const DomainParticipantExtendedQos &extended_qos, DomainParticipantListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Participant.

Parameters:
Returns:

DomainParticipant pointer. (nullptr if not created.)

DomainParticipant *create_participant_with_default_profile()

Create a Participant with default domain id and qos.

Returns:

DomainParticipant pointer. (nullptr if not created.)

DomainParticipant *create_participant_with_default_profile(DomainParticipantListener *listener, const StatusMask &mask)

Create a Participant with default domain id and qos.

Parameters:
Returns:

DomainParticipant pointer. (nullptr if not created.)

DomainParticipant *create_participant_with_profile(DomainId_t domain_id, const std::string &profile_name, DomainParticipantListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Participant.

Parameters:
  • domain_id – Domain Id.

  • profile_name – Participant profile name.

  • listenerDomainParticipantListener Pointer (default: nullptr)

  • maskStatusMask Reference (default: all)

Returns:

DomainParticipant pointer. (nullptr if not created.)

DomainParticipant *create_participant_with_profile(const std::string &profile_name, DomainParticipantListener *listener = nullptr, const StatusMask &mask = StatusMask::all())

Create a Participant.

Parameters:
Returns:

DomainParticipant pointer. (nullptr if not created.)

DomainParticipant *lookup_participant(DomainId_t domain_id) const

This operation retrieves a previously created DomainParticipant belonging to specified domain_id. If no such DomainParticipant exists, the operation will return ‘nullptr’. If multiple DomainParticipant entities belonging to that domain_id exist, then the operation will return one of them. It is not specified which one.

Parameters:

domain_id

Returns:

previously created DomainParticipant within the specified domain

std::vector<DomainParticipant*> lookup_participants(DomainId_t domain_id) const

Returns all participants that belongs to the specified domain_id.

Parameters:

domain_id

Returns:

previously created DomainParticipants within the specified domain

ReturnCode_t get_default_participant_qos(DomainParticipantQos &qos) const

This operation retrieves the default value of the DomainParticipant QoS, that is, the QoS policies which will be used for newly created DomainParticipant entities in the case where the QoS policies are defaulted in the create_participant operation. The values retrieved get_default_participant_qos will match the set of values specified on the last successful call to set_default_participant_qos, or else, if the call was never made, the default values.

Parameters:

qosDomainParticipantQos where the qos is returned

Returns:

RETCODE_OK

const DomainParticipantQos &get_default_participant_qos() const

This operation retrieves the default value of the DomainParticipant QoS, that is, the QoS policies which will be used for newly created DomainParticipant entities in the case where the QoS policies are defaulted in the create_participant operation. The values retrieved get_default_participant_qos will match the set of values specified on the last successful call to set_default_participant_qos, or else, if the call was never made, the default values.

Returns:

A reference to the default DomainParticipantQos

ReturnCode_t set_default_participant_qos(const DomainParticipantQos &qos)

This operation sets a default value of the DomainParticipant QoS policies which will be used for newly created DomainParticipant entities in the case where the QoS policies are defaulted in the create_participant operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return INCONSISTENT_POLICY.

The special value PARTICIPANT_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_participant_qos operation had never been called.

Parameters:

qosDomainParticipantQos to be set

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

ReturnCode_t get_participant_qos_from_profile(const std::string &profile_name, DomainParticipantQos &qos) const

Fills the DomainParticipantQos with the values of the XML profile.

Parameters:
Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_participant_qos_from_xml(const std::string &xml, DomainParticipantQos &qos) const

Fills the DomainParticipantQos with the first DomainParticipant profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDomainParticipantQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_participant_qos_from_xml(const std::string &xml, DomainParticipantQos &qos, const std::string &profile_name) const

Fills the DomainParticipantQos with the DomainParticipant profile with profile_name to be found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDomainParticipantQos object where the qos is returned.

  • profile_nameDomainParticipant profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_participant_qos_from_xml(const std::string &xml, DomainParticipantQos &qos) const

Fills the DomainParticipantQos with the default DomainParticipant profile found in the provided XML (if there is).

Note

This method does not update the default participant qos (returned by get_default_participant_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDomainParticipantQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_participant_extended_qos_from_profile(const std::string &profile_name, DomainParticipantExtendedQos &extended_qos) const

Fills the DomainParticipantExtendedQos with the values of the XML profile.

Parameters:
Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_participant_extended_qos_from_xml(const std::string &xml, DomainParticipantExtendedQos &extended_qos) const

Fills the DomainParticipantExtendedQos with the first DomainParticipant profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the extended_qos structure.

  • extended_qosDomainParticipantExtendedQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_participant_extended_qos_from_xml(const std::string &xml, DomainParticipantExtendedQos &extended_qos, const std::string &profile_name) const

Fills the DomainParticipantExtendedQos with the DomainParticipant profile with profile_name to be found in the provided XML.

Parameters:
Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_participant_extended_qos_from_xml(const std::string &xml, DomainParticipantExtendedQos &extended_qos) const

Fills the DomainParticipantExtendedQos with the default DomainParticipant profile found in the provided XML (if there is).

Note

This method does not update the default participant extended qos.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the extended_qos structure.

  • extended_qosDomainParticipantExtendedQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_participant_extended_qos_from_default_profile(DomainParticipantExtendedQos &extended_qos) const

Fills the DomainParticipantExtendedQos with the values of the default XML profile.

Parameters:

extended_qosDomainParticipantExtendedQos object where the domain and qos are returned.

Returns:

RETCODE_OK

ReturnCode_t delete_participant(DomainParticipant *part)

Remove a Participant and all associated publishers and subscribers.

Parameters:

part – Pointer to the participant.

Returns:

RETCODE_PRECONDITION_NOT_MET if the participant has active entities, RETCODE_OK if the participant is correctly deleted and RETCODE_ERROR otherwise.

ReturnCode_t load_profiles()

Load profiles from default XML file.

Returns:

RETCODE_OK

ReturnCode_t load_XML_profiles_file(const std::string &xml_profile_file)

Load profiles from XML file.

Parameters:

xml_profile_file – XML profile file.

Returns:

RETCODE_OK if it is correctly loaded, RETCODE_ERROR otherwise.

ReturnCode_t load_XML_profiles_string(const char *data, size_t length)

Load profiles from XML string.

Parameters:
  • data – buffer containing xml data.

  • length – length of data

Returns:

RETCODE_OK if it is correctly loaded, RETCODE_ERROR otherwise.

ReturnCode_t check_xml_static_discovery(std::string &xml_file)

Check the validity of the provided static discovery XML file

Parameters:

xml_file – xml file path

Returns:

RETCODE_OK if the validation is successful, RETCODE_ERROR otherwise.

ReturnCode_t get_qos(DomainParticipantFactoryQos &qos) const

This operation returns the value of the DomainParticipantFactory QoS policies.

Parameters:

qos – DomaParticipantFactoryQos reference where the qos is returned

Returns:

RETCODE_OK

ReturnCode_t set_qos(const DomainParticipantFactoryQos &qos)

This operation sets the value of the DomainParticipantFactory QoS policies. These policies control the behavior of the object a factory for entities.

Note that despite having QoS, the DomainParticipantFactory is not an Entity.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return INCONSISTENT_POLICY.

Parameters:

qosDomainParticipantFactoryQos to be set.

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

ReturnCode_t get_library_settings(LibrarySettings &library_settings) const

This operation returns the value of the DomainParticipant library settings.

Parameters:

library_settings – LibrarySettings reference where the settings are returned.

Returns:

RETCODE_OK

ReturnCode_t set_library_settings(const LibrarySettings &library_settings)

This operation sets the library settings.

Library settings must be set before enabling the DomainParticipants. Otherwise, failure of the setting operation is expected.

Parameters:

library_settings – LibrarySettings to be set.

Returns:

RETCODE_PRECONDITION_NOT_MET if any DomainParticipant is already enabled. RETCODE_OK otherwise.

ReturnCode_t get_dynamic_type_builder_from_xml_by_name(const std::string &type_name, DynamicTypeBuilder::_ref_type &type)

Get the DynamicType defined in XML file. The XML file shall be previously loaded.

Parameters:
  • type_name – Dynamic type name.

  • type – Reference where the Dynamic type builder is returned.

Returns:

RETCODE_BAD_PARAMETER if type_name is empty. RETCODE_NO_DATA if type_name is unknown. RETCODE_OK otherwise.

xtypes::ITypeObjectRegistry &type_object_registry()

Return the TypeObjectRegistry member to access the public API.

Returns:

const xtypes::TypeObjectRegistry reference.

Public Static Functions

static DomainParticipantFactory *get_instance()

Returns the DomainParticipantFactory singleton instance.

Returns:

A raw pointer to the DomainParticipantFactory singleton instance.

static std::shared_ptr<DomainParticipantFactory> get_shared_instance()

Returns the DomainParticipantFactory singleton instance.

Returns:

A shared pointer to the DomainParticipantFactory singleton instance.

20.1.2.3. DomainParticipantFactoryQos
class DomainParticipantFactoryQos

Class DomainParticipantFactoryQos, contains all the possible Qos that can be set for a determined participant. Please consult each of them to check for implementation details and default values.

Public Functions

inline DomainParticipantFactoryQos()

Constructor.

inline virtual ~DomainParticipantFactoryQos()

Destructor.

inline const EntityFactoryQosPolicy &entity_factory() const

Getter for EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference

inline EntityFactoryQosPolicy &entity_factory()

Getter for EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference

inline void entity_factory(const EntityFactoryQosPolicy &entity_factory)

Setter for EntityFactoryQosPolicy

Parameters:

entity_factoryEntityFactoryQosPolicy

inline rtps::ThreadSettings &shm_watchdog_thread()

Getter for SHM watchdog ThreadSettings

Returns:

rtps::ThreadSettings reference

inline const rtps::ThreadSettings &shm_watchdog_thread() const

Getter for SHM watchdog ThreadSettings

Returns:

rtps::ThreadSettings reference

inline void shm_watchdog_thread(const rtps::ThreadSettings &value)

Setter for the SHM watchdog ThreadSettings

Parameters:

value – New ThreadSettings to be set

inline rtps::ThreadSettings &file_watch_threads()

Getter for file watch related ThreadSettings

Returns:

rtps::ThreadSettings reference

inline const rtps::ThreadSettings &file_watch_threads() const

Getter for file watch related ThreadSettings

Returns:

rtps::ThreadSettings reference

inline void file_watch_threads(const rtps::ThreadSettings &value)

Setter for the file watch related ThreadSettings

Parameters:

value – New ThreadSettings to be set

20.1.2.4. DomainParticipantListener
class DomainParticipantListener : public eprosima::fastdds::dds::PublisherListener, public eprosima::fastdds::dds::SubscriberListener, public eprosima::fastdds::dds::TopicListener

Class DomainParticipantListener, overrides behaviour towards certain events.

Public Functions

inline DomainParticipantListener()

Constructor.

inline virtual ~DomainParticipantListener()

Destructor.

inline virtual void on_participant_discovery(DomainParticipant *participant, fastdds::rtps::ParticipantDiscoveryStatus reason, const ParticipantBuiltinTopicData &info, bool &should_be_ignored)

This method is called when a new Participant is discovered, or a previously discovered participant changes its QOS or is removed.

Parameters:
  • participant[out] Pointer to the Participant which discovered the remote participant.

  • reason[out] Reason of the change in the status of the discovered participant.

  • info[out] Remote participant information. User can take ownership of the object.

  • should_be_ignored[out] Flag to indicate the library to automatically ignore the discovered Participant.

inline virtual void onParticipantAuthentication(DomainParticipant *participant, rtps::ParticipantAuthenticationInfo &&info)

This method is called when a new Participant is authenticated.

Parameters:
  • participant[out] Pointer to the authenticated Participant.

  • info[out] Remote participant authentication information. User can take ownership of the object.

inline virtual void on_data_reader_discovery(DomainParticipant *participant, rtps::ReaderDiscoveryStatus reason, const SubscriptionBuiltinTopicData &info, bool &should_be_ignored)

This method is called when a new DataReader is discovered, or a previously discovered DataReader changes its QOS or is removed.

Parameters:
  • participant[in] Pointer to the Participant which discovered the remote reader.

  • reason[in] The reason motivating this method to be called.

  • info[in] Remote reader information.

  • should_be_ignored[out] Flag to indicate the library to automatically ignore the discovered reader.

inline virtual void on_data_writer_discovery(DomainParticipant *participant, rtps::WriterDiscoveryStatus reason, const PublicationBuiltinTopicData &info, bool &should_be_ignored)

This method is called when a new DataWriter is discovered, or a previously discovered DataWriter changes its QOS or is removed.

Parameters:
  • participant[in] Pointer to the Participant which discovered the remote writer.

  • reason[in] The reason motivating this method to be called.

  • info[in] Remote writer information.

  • should_be_ignored[out] Flag to indicate the library to automatically ignore the discovered writer.

20.1.2.5. DomainParticipantQos
class DomainParticipantQos

Class DomainParticipantQos, contains all the possible Qos that can be set for a determined participant. Please consult each of them to check for implementation details and default values.

Subclassed by eprosima::fastdds::dds::DomainParticipantExtendedQos

Public Types

using FlowControllerDescriptorList = std::vector<std::shared_ptr<fastdds::rtps::FlowControllerDescriptor>>

User defined flow controllers to use alongside.

Since

2.4.0

Public Functions

inline DomainParticipantQos()

Constructor.

inline virtual ~DomainParticipantQos()

Destructor.

inline const UserDataQosPolicy &user_data() const

Getter for UserDataQosPolicy

Returns:

UserDataQosPolicy reference

inline UserDataQosPolicy &user_data()

Getter for UserDataQosPolicy

Returns:

UserDataQosPolicy reference

inline void user_data(const UserDataQosPolicy &value)

Setter for UserDataQosPolicy

Parameters:

valueUserDataQosPolicy

inline const EntityFactoryQosPolicy &entity_factory() const

Getter for EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference

inline EntityFactoryQosPolicy &entity_factory()

Getter for EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference

inline void entity_factory(const EntityFactoryQosPolicy &value)

Setter for EntityFactoryQosPolicy

Parameters:

valueEntityFactoryQosPolicy

inline const ParticipantResourceLimitsQos &allocation() const

Getter for ParticipantResourceLimitsQos

Returns:

ParticipantResourceLimitsQos reference

inline ParticipantResourceLimitsQos &allocation()

Getter for ParticipantResourceLimitsQos

Returns:

ParticipantResourceLimitsQos reference

inline void allocation(const ParticipantResourceLimitsQos &allocation)

Setter for ParticipantResourceLimitsQos

Parameters:

allocation – ParticipantResourceLimitsQos

inline const PropertyPolicyQos &properties() const

Getter for PropertyPolicyQos

Returns:

PropertyPolicyQos reference

inline PropertyPolicyQos &properties()

Getter for PropertyPolicyQos

Returns:

PropertyPolicyQos reference

inline void properties(const PropertyPolicyQos &properties)

Setter for PropertyPolicyQos

Parameters:

properties – PropertyPolicyQos

inline const WireProtocolConfigQos &wire_protocol() const

Getter for WireProtocolConfigQos

Returns:

WireProtocolConfigQos reference

inline WireProtocolConfigQos &wire_protocol()

Getter for WireProtocolConfigQos

Returns:

WireProtocolConfigQos reference

inline void wire_protocol(const WireProtocolConfigQos &wire_protocol)

Setter for WireProtocolConfigQos

Parameters:

wire_protocolWireProtocolConfigQos

inline const TransportConfigQos &transport() const

Getter for TransportConfigQos

Returns:

TransportConfigQos reference

inline TransportConfigQos &transport()

Getter for TransportConfigQos

Returns:

TransportConfigQos reference

inline void transport(const TransportConfigQos &transport)

Setter for TransportConfigQos

Parameters:

transportTransportConfigQos

inline const fastcdr::string_255 &name() const

Getter for the Participant name

Returns:

name

inline fastcdr::string_255 &name()

Getter for the Participant name

Returns:

name

inline void name(const fastcdr::string_255 &value)

Setter for the Participant name

Parameters:

value – New name to be set

inline FlowControllerDescriptorList &flow_controllers()

Getter for FlowControllerDescriptorList

Returns:

FlowControllerDescriptorList reference

bool compare_flow_controllers(const DomainParticipantQos &qos) const

Compares the flow controllers of two DomainParticipantQos element-wise.

Parameters:

qos – The DomainParticipantQos to compare with.

Returns:

true if the flow controllers are the same, false otherwise.

inline const FlowControllerDescriptorList &flow_controllers() const

Getter for FlowControllerDescriptorList

Returns:

FlowControllerDescriptorList reference

inline rtps::ThreadSettings &builtin_controllers_sender_thread()

Getter for builtin flow controllers sender threads ThreadSettings

Returns:

rtps::ThreadSettings reference

inline const rtps::ThreadSettings &builtin_controllers_sender_thread() const

Getter for builtin flow controllers sender threads ThreadSettings

Returns:

rtps::ThreadSettings reference

void setup_transports(rtps::BuiltinTransports transports, const rtps::BuiltinTransportsOptions &options = rtps::BuiltinTransportsOptions())

Provides a way of easily configuring transport related configuration on certain pre-defined scenarios with certain options.

Parameters:
  • transports – Defines the transport configuration scenario to setup.

  • options – Defines the options to be used in the transport configuration.

inline void builtin_controllers_sender_thread(const rtps::ThreadSettings &value)

Setter for the builtin flow controllers sender threads ThreadSettings

Parameters:

value – New ThreadSettings to be set

inline rtps::ThreadSettings &timed_events_thread()

Getter for timed event ThreadSettings

Returns:

rtps::ThreadSettings reference

inline const rtps::ThreadSettings &timed_events_thread() const

Getter for timed event ThreadSettings

Returns:

rtps::ThreadSettings reference

inline void timed_events_thread(const rtps::ThreadSettings &value)

Setter for the timed event ThreadSettings

Parameters:

value – New ThreadSettings to be set

inline rtps::ThreadSettings &discovery_server_thread()

Getter for discovery server ThreadSettings

Returns:

rtps::ThreadSettings reference

inline const rtps::ThreadSettings &discovery_server_thread() const

Getter for discovery server ThreadSettings

Returns:

rtps::ThreadSettings reference

inline void discovery_server_thread(const rtps::ThreadSettings &value)

Setter for the discovery server ThreadSettings

Parameters:

value – New ThreadSettings to be set

inline rtps::ThreadSettings &typelookup_service_thread()

Getter for TypeLookup service ThreadSettings

Returns:

rtps::ThreadSettings reference

inline const rtps::ThreadSettings &typelookup_service_thread() const

Getter for TypeLookup service ThreadSettings

Returns:

rtps::ThreadSettings reference

inline void typelookup_service_thread(const rtps::ThreadSettings &value)

Setter for the TypeLookup service ThreadSettings

Parameters:

value – New ThreadSettings to be set

inline rtps::ThreadSettings &security_log_thread()

Getter for security log ThreadSettings

Returns:

rtps::ThreadSettings reference

inline const rtps::ThreadSettings &security_log_thread() const

Getter for security log ThreadSettings

Returns:

rtps::ThreadSettings reference

inline void security_log_thread(const rtps::ThreadSettings &value)

Setter for the security log ThreadSettings

Parameters:

value – New ThreadSettings to be set

const DomainParticipantQos eprosima::fastdds::dds::PARTICIPANT_QOS_DEFAULT
20.1.2.6. DomainParticipantExtendedQos
class DomainParticipantExtendedQos : public eprosima::fastdds::dds::DomainParticipantQos

Public Functions

inline DomainParticipantExtendedQos()

Constructor.

inline virtual ~DomainParticipantExtendedQos()

Destructor.

inline const uint32_t &domainId() const

Getter for domainId

Returns:

domainId reference

inline uint32_t &domainId()

Getter for domainId

Returns:

domainId reference

20.1.3. Publisher

20.1.3.1. DataWriter
class DataWriter : public eprosima::fastdds::dds::DomainEntity

Class DataWriter, contains the actual implementation of the behaviour of the DataWriter.

Public Types

enum class LoanInitializationKind

How to initialize samples loaned with loan_sample

Values:

enumerator NO_LOAN_INITIALIZATION

Do not perform initialization of sample.

This is the default initialization scheme of loaned samples. It is the fastest scheme, but implies the user should take care of writing every field on the data type before calling write on the loaned sample.

enumerator ZERO_LOAN_INITIALIZATION

Initialize all memory with zero-valued bytes.

The contents of the loaned sample will be zero-initialized upon return of loan_sample.

enumerator CONSTRUCTED_LOAN_INITIALIZATION

Use in-place constructor initialization.

This will call the constructor of the data type over the memory space being returned by loan_sample.

Public Functions

virtual ReturnCode_t enable() override

This operation enables the DataWriter.

Returns:

RETCODE_OK is successfully enabled. RETCODE_PRECONDITION_NOT_MET if the Publisher creating this DataWriter is not enabled.

ReturnCode_t write(const void *const data)

Write data to the topic.

Parameters:

data – Pointer to the data

Returns:

RETCODE_OK if the data is correctly sent or a ReturnCode related to the specific error otherwise.

ReturnCode_t write(const void *const data, fastdds::rtps::WriteParams &params)

Write data with params to the topic.

Parameters:
  • data – Pointer to the data

  • params – Extra write parameters.

Returns:

RETCODE_OK if the data is correctly sent or a ReturnCode related to the specific error otherwise.

ReturnCode_t write(const void *const data, const InstanceHandle_t &handle)

Write data with handle.

The special value HANDLE_NIL can be used for the parameter handle.This indicates that the identity of the instance should be automatically deduced from the instance_data (by means of the key).

Parameters:
  • data – Pointer to the data

  • handle – InstanceHandle_t.

Returns:

RETCODE_PRECONDITION_NOT_MET if the handle introduced does not match with the one associated to the data, RETCODE_OK if the data is correctly sent and RETCODE_ERROR otherwise.

ReturnCode_t write_w_timestamp(const void *const data, const InstanceHandle_t &handle, const fastdds::dds::Time_t &timestamp)

This operation performs the same function as write except that it also provides the value for the source_timestamp that is made available to DataReader objects by means of the eprosima::fastdds::dds::SampleInfo::source_timestamp attribute “source_timestamp” inside the SampleInfo. The constraints on the values of the handle parameter and the corresponding error behavior are the same specified for the write operation. This operation may block and return RETCODE_TIMEOUT under the same circumstances described for the write operation. This operation may return RETCODE_OUT_OF_RESOURCES, RETCODE_PRECONDITION_NOT_MET or RETCODE_BAD_PARAMETER under the same circumstances described for the write operation.

Parameters:
  • data – Pointer to the data

  • handle – InstanceHandle_t

  • timestampTime_t used to set the source_timestamp.

Returns:

Any of the standard return codes.

InstanceHandle_t register_instance(const void *const instance)

Informs that the application will be modifying a particular instance.

It gives an opportunity to the middleware to pre-configure itself to improve performance.

Parameters:

instance[in] Sample used to get the instance’s key.

Returns:

Handle containing the instance’s key. This handle could be used in successive write or dispose operations. In case of error, HANDLE_NIL will be returned.

InstanceHandle_t register_instance_w_timestamp(const void *const instance, const fastdds::dds::Time_t &timestamp)

This operation performs the same function as register_instance and can be used instead of register_instance in the cases where the application desires to specify the value for the source_timestamp. The source_timestamp potentially affects the relative order in which readers observe events from multiple writers. See the QoS policy DESTINATION_ORDER.

This operation may block and return RETCODE_TIMEOUT under the same circumstances described for the write operation.

This operation may return RETCODE_OUT_OF_RESOURCES under the same circumstances described for the write operation.

Parameters:
  • instance – Sample used to get the instance’s key.

  • timestampTime_t used to set the source_timestamp.

Returns:

Handle containing the instance’s key.

ReturnCode_t unregister_instance(const void *const instance, const InstanceHandle_t &handle)

This operation reverses the action of register_instance.

It should only be called on an instance that is currently registered. Informs the middleware that the DataWriter is not intending to modify any more of that data instance. Also indicates that the middleware can locally remove all information regarding that instance.

Parameters:
  • instance[in] Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • handle[in] Instance’s key to be unregistered.

Returns:

Returns the operation’s result. If the operation finishes successfully, RETCODE_OK is returned.

ReturnCode_t unregister_instance_w_timestamp(const void *const instance, const InstanceHandle_t &handle, const fastdds::dds::Time_t &timestamp)

This operation performs the same function as unregister_instance and can be used instead of unregister_instance in the cases where the application desires to specify the value for the source_timestamp. The source_timestamp potentially affects the relative order in which readers observe events from multiple writers. See the QoS policy DESTINATION_ORDER.

The constraints on the values of the handle parameter and the corresponding error behavior are the same specified for the unregister_instance operation.

This operation may block and return RETCODE_TIMEOUT under the same circumstances described for the write operation

Parameters:
  • instance – Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • handle – Instance’s key to be unregistered.

  • timestampTime_t used to set the source_timestamp.

Returns:

Handle containing the instance’s key.

ReturnCode_t get_key_value(void *key_holder, const InstanceHandle_t &handle)

This operation can be used to retrieve the instance key that corresponds to an instance_handle. The operation will only fill the fields that form the key inside the key_holder instance.

This operation may return BAD_PARAMETER if the InstanceHandle_t handle does not correspond to an existing data-object known to the DataWriter. If the implementation is not able to check invalid handles then the result in this situation is unspecified.

Parameters:
  • key_holder[inout] Sample where the key fields will be returned.

  • handle[in] Handle to the instance to retrieve the key values from.

Returns:

Any of the standard return codes.

InstanceHandle_t lookup_instance(const void *const instance) const

NOT YET IMPLEMENTED

Takes as a parameter an instance and returns a handle that can be used in subsequent operations that accept an instance handle as an argument. The instance parameter is only used for the purpose of examining the fields that define the key.

Parameters:

instance[in] Data pointer to the sample

Returns:

handle of the given instance

const fastdds::rtps::GUID_t &guid() const

Returns the DataWriter’s GUID

Returns:

Reference to the DataWriter GUID

InstanceHandle_t get_instance_handle() const

Returns the DataWriter’s InstanceHandle

Returns:

Copy of the DataWriter InstanceHandle

TypeSupport get_type() const

Get data type associated to the DataWriter

Returns:

Copy of the TypeSupport

ReturnCode_t wait_for_acknowledgments(const fastdds::dds::Duration_t &max_wait)

Waits the current thread until all writers have received their acknowledgments.

Parameters:

max_wait – Maximum blocking time for this operation

Returns:

RETCODE_OK if the DataWriter receive the acknowledgments before the time expires and RETCODE_ERROR otherwise

ReturnCode_t get_offered_deadline_missed_status(OfferedDeadlineMissedStatus &status)

Returns the offered deadline missed status.

Parameters:

status[out] Deadline missed status struct

Returns:

RETCODE_OK

ReturnCode_t get_offered_incompatible_qos_status(OfferedIncompatibleQosStatus &status)

Returns the offered incompatible qos status.

Parameters:

status[out] Offered incompatible qos status struct

Returns:

RETCODE_OK

ReturnCode_t get_publication_matched_status(PublicationMatchedStatus &status) const

Returns the publication matched status.

Parameters:

status[out] publication matched status struct

Returns:

RETCODE_OK

ReturnCode_t set_qos(const DataWriterQos &qos)

Establishes the DataWriterQos for this DataWriter.

Parameters:

qosDataWriterQos to be set

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const DataWriterQos &get_qos() const

Retrieves the DataWriterQos for this DataWriter.

Returns:

Reference to the current DataWriterQos

ReturnCode_t get_qos(DataWriterQos &qos) const

Fills the DataWriterQos with the values of this DataWriter.

Parameters:

qosDataWriterQos object where the qos is returned.

Returns:

RETCODE_OK

Topic *get_topic() const

Retrieves the topic for this DataWriter.

Returns:

Pointer to the associated Topic

const DataWriterListener *get_listener() const

Retrieves the listener for this DataWriter.

Returns:

Pointer to the DataWriterListener

ReturnCode_t set_listener(DataWriterListener *listener)

Modifies the DataWriterListener, sets the mask to StatusMask::all()

Parameters:

listener – new value for the DataWriterListener

Returns:

RETCODE_OK

ReturnCode_t set_listener(DataWriterListener *listener, const StatusMask &mask)

Modifies the DataWriterListener.

Parameters:
Returns:

RETCODE_OK

ReturnCode_t dispose(const void *const data, const InstanceHandle_t &handle)

This operation requests the middleware to delete the data (the actual deletion is postponed until there is no more use for that data in the whole system). In general, applications are made aware of the deletion by means of operations on the DataReader objects that already knew that instance. This operation does not modify the value of the instance. The instance parameter is passed just for the purposes of identifying the instance. When this operation is used, the Service will automatically supply the value of the source_timestamp that is made available to DataReader objects by means of the source_timestamp attribute inside the SampleInfo. The constraints on the values of the handle parameter and the corresponding error behavior are the same specified for the unregister_instance operation.

Parameters:
  • data[in] Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • handle[in] InstanceHandle of the data

Returns:

RETCODE_PRECONDITION_NOT_MET if the handle introduced does not match with the one associated to the data, RETCODE_OK if the data is correctly sent and RETCODE_ERROR otherwise.

ReturnCode_t dispose_w_timestamp(const void *const instance, const InstanceHandle_t &handle, const fastdds::dds::Time_t &timestamp)

This operation performs the same functions as dispose except that the application provides the value for the source_timestamp that is made available to DataReader objects by means of the source_timestamp attribute inside the SampleInfo.

The constraints on the values of the handle parameter and the corresponding error behavior are the same specified for the dispose operation.

This operation may return RETCODE_PRECONDITION_NOT_MET and RETCODE_BAD_PARAMETER under the same circumstances described for the dispose operation.

This operation may return RETCODE_TIMEOUT and RETCODE_OUT_OF_RESOURCES under the same circumstances described for the write operation.

Parameters:
  • instance – Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • handle – Instance’s key to be disposed.

  • timestampTime_t used to set the source_timestamp.

Returns:

FASTDDS_EXPORTED_API

ReturnCode_t get_liveliness_lost_status(LivelinessLostStatus &status)

Returns the liveliness lost status.

Parameters:

status – Liveliness lost status struct

Returns:

RETCODE_OK

const Publisher *get_publisher() const

Getter for the Publisher that creates this DataWriter.

Returns:

Pointer to the Publisher

ReturnCode_t assert_liveliness()

This operation manually asserts the liveliness of the DataWriter. This is used in combination with the LivelinessQosPolicy to indicate to the Service that the entity remains active. This operation need only be used if the LIVELINESS setting is either MANUAL_BY_PARTICIPANT or MANUAL_BY_TOPIC. Otherwise, it has no effect.

Note

Writing data via the write operation on a DataWriter asserts liveliness on the DataWriter itself and its DomainParticipant. Consequently the use of assert_liveliness is only needed if the application is not writing data regularly.

Returns:

RETCODE_OK if asserted, RETCODE_ERROR otherwise

ReturnCode_t get_matched_subscription_data(SubscriptionBuiltinTopicData &subscription_data, const InstanceHandle_t &subscription_handle) const

Retrieves in a subscription associated with the DataWriter.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:
  • subscription_data[out] subscription data struct

  • subscription_handle – InstanceHandle_t of the subscription

Returns:

RETCODE_OK

ReturnCode_t get_matched_subscriptions(std::vector<InstanceHandle_t> &subscription_handles) const

Fills the given vector with the InstanceHandle_t of matched DataReaders.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

subscription_handles[out] Vector where the InstanceHandle_t are returned

Returns:

RETCODE_OK

ReturnCode_t clear_history(size_t *removed)

Clears the DataWriter history.

Parameters:

removed – size_t pointer to return the size of the data removed

Returns:

RETCODE_OK if the samples are removed and RETCODE_ERROR otherwise

ReturnCode_t loan_sample(void *&sample, LoanInitializationKind initialization = LoanInitializationKind::NO_LOAN_INITIALIZATION)

Get a pointer to the internal pool where the user could directly write.

This method can only be used on a DataWriter for a plain data type. It will provide the user with a pointer to an internal buffer where the data type can be prepared for sending.

When using NO_LOAN_INITIALIZATION on the initialization parameter, which is the default, no assumptions should be made on the contents where the pointer points to, as it may be an old pointer being reused. See LoanInitializationKind for more details.

Once the sample has been prepared, it can then be published by calling write. After a successful call to write, the middleware takes ownership of the loaned pointer again, and the user should not access that memory again.

If, for whatever reason, the sample is not published, the loan can be returned by calling discard_loan.

Parameters:
  • sample[out] Pointer to the sample on the internal pool.

  • initialization[in] How to initialize the loaned sample.

Returns:

RETCODE_ILLEGAL_OPERATION when the data type does not support loans.

Returns:

RETCODE_NOT_ENABLED if the writer has not been enabled.

Returns:

RETCODE_OUT_OF_RESOURCES if the pool has been exhausted.

Returns:

RETCODE_OK if a pointer to a sample is successfully obtained.

ReturnCode_t discard_loan(void *&sample)

Discards a loaned sample pointer.

See the description on loan_sample for how and when to call this method.

Parameters:

sample[inout] Pointer to the previously loaned sample.

Returns:

RETCODE_ILLEGAL_OPERATION when the data type does not support loans.

Returns:

RETCODE_NOT_ENABLED if the writer has not been enabled.

Returns:

RETCODE_BAD_PARAMETER if the pointer does not correspond to a loaned sample.

Returns:

RETCODE_OK if the loan is successfully discarded.

ReturnCode_t get_sending_locators(rtps::LocatorList &locators) const

Get the list of locators from which this DataWriter may send data.

Parameters:

locators[out] LocatorList where the list of locators will be stored.

Returns:

NOT_ENABLED if the reader has not been enabled.

Returns:

OK if a list of locators is returned.

ReturnCode_t wait_for_acknowledgments(const void *const instance, const InstanceHandle_t &handle, const fastdds::dds::Duration_t &max_wait)

Block the current thread until the writer has received the acknowledgment corresponding to the given instance. Operations performed on the same instance while the current thread is waiting will not be taken into consideration, i.e. this method may return RETCODE_OK with those operations unacknowledged.

Parameters:
  • instance – Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • handle – Instance handle of the data.

  • max_wait – Maximum blocking time for this operation.

Returns:

RETCODE_NOT_ENABLED if the writer has not been enabled.

Returns:

RETCODE_BAD_PARAMETER if instance is not a valid pointer.

Returns:

RETCODE_PRECONDITION_NOT_MET if the topic does not have a key, the key is unknown to the writer, or the key is not consistent with handle.

Returns:

RETCODE_OK if the DataWriter received the acknowledgments before the time expired.

Returns:

RETCODE_TIMEOUT otherwise.

ReturnCode_t get_publication_builtin_topic_data(PublicationBuiltinTopicData &publication_data) const

Retrieve the publication data discovery information.

Parameters:

publication_data[out] The publication data discovery information.

Returns:

NOT_ENABLED if the writer has not been enabled.

Returns:

OK if the publication data is returned.

20.1.3.2. DataWriterListener
class DataWriterListener

Class DataWriterListener, allows the end user to implement callbacks triggered by certain events.

Subclassed by eprosima::fastdds::dds::PublisherListener

Public Functions

inline DataWriterListener()

Constructor.

inline virtual ~DataWriterListener()

Destructor.

inline virtual void on_publication_matched(DataWriter *writer, const PublicationMatchedStatus &info)

This method is called when the DataWriter is matched (or unmatched) against an endpoint.

Parameters:
  • writer – Pointer to the associated DataWriter

  • info – Information regarding the matched DataReader

inline virtual void on_offered_deadline_missed(DataWriter *writer, const OfferedDeadlineMissedStatus &status)

A method called when a deadline is missed

Parameters:
  • writer – Pointer to the associated DataWriter

  • status – The deadline missed status

inline virtual void on_offered_incompatible_qos(DataWriter *writer, const OfferedIncompatibleQosStatus &status)

A method called when an incompatible QoS is offered

Parameters:
  • writer – Pointer to the associated DataWriter

  • status – The deadline missed status

inline virtual void on_liveliness_lost(DataWriter *writer, const LivelinessLostStatus &status)

Method called when the liveliness of a DataWriter is lost.

Parameters:
  • writer – Pointer to the associated DataWriter

  • status – The liveliness lost status

inline virtual void on_unacknowledged_sample_removed(DataWriter *writer, const InstanceHandle_t &instance)

Method called when a sample has been removed unacknowledged.

Parameters:
  • writer – Pointer to the associated DataWriter

  • instance – Handle to the instance the sample was removed from

20.1.3.3. DataWriterQos
class DataWriterQos

Class DataWriterQos, containing all the possible Qos that can be set for a determined DataWriter. Although these values can be and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

Subclassed by eprosima::fastdds::statistics::dds::DataWriterQos

Public Functions

DataWriterQos()

Constructor.

~DataWriterQos() = default

Destructor.

inline DurabilityQosPolicy &durability()

Getter for DurabilityQosPolicy

Returns:

DurabilityQosPolicy reference

inline const DurabilityQosPolicy &durability() const

Getter for DurabilityQosPolicy

Returns:

DurabilityQosPolicy reference

inline void durability(const DurabilityQosPolicy &durability)

Setter for DurabilityQosPolicy

Parameters:

durability – new value for the DurabilityQosPolicy

inline DurabilityServiceQosPolicy &durability_service()

Getter for DurabilityServiceQosPolicy

Returns:

DurabilityServiceQosPolicy reference

inline const DurabilityServiceQosPolicy &durability_service() const

Getter for DurabilityServiceQosPolicy

Returns:

DurabilityServiceQosPolicy reference

inline void durability_service(const DurabilityServiceQosPolicy &durability_service)

Setter for DurabilityServiceQosPolicy

Parameters:

durability_service – new value for the DurabilityServiceQosPolicy

inline DeadlineQosPolicy &deadline()

Getter for DeadlineQosPolicy

Returns:

DeadlineQosPolicy reference

inline const DeadlineQosPolicy &deadline() const

Getter for DeadlineQosPolicy

Returns:

DeadlineQosPolicy reference

inline void deadline(const DeadlineQosPolicy &deadline)

Setter for DeadlineQosPolicy

Parameters:

deadline – new value for the DeadlineQosPolicy

inline LatencyBudgetQosPolicy &latency_budget()

Getter for LatencyBudgetQosPolicy

Returns:

LatencyBudgetQosPolicy reference

inline const LatencyBudgetQosPolicy &latency_budget() const

Getter for LatencyBudgetQosPolicy

Returns:

LatencyBudgetQosPolicy reference

inline void latency_budget(const LatencyBudgetQosPolicy &latency_budget)

Setter for LatencyBudgetQosPolicy

Parameters:

latency_budget – new value for the LatencyBudgetQosPolicy

inline LivelinessQosPolicy &liveliness()

Getter for LivelinessQosPolicy

Returns:

LivelinessQosPolicy reference

inline const LivelinessQosPolicy &liveliness() const

Getter for LivelinessQosPolicy

Returns:

LivelinessQosPolicy reference

inline void liveliness(const LivelinessQosPolicy &liveliness)

Setter for LivelinessQosPolicy

Parameters:

liveliness – new value for the LivelinessQosPolicy

inline ReliabilityQosPolicy &reliability()

Getter for ReliabilityQosPolicy

Returns:

ReliabilityQosPolicy reference

inline const ReliabilityQosPolicy &reliability() const

Getter for ReliabilityQosPolicy

Returns:

ReliabilityQosPolicy reference

inline void reliability(const ReliabilityQosPolicy &reliability)

Setter for ReliabilityQosPolicy

Parameters:

reliability – new value for the ReliabilityQosPolicy

inline DestinationOrderQosPolicy &destination_order()

Getter for DestinationOrderQosPolicy

Returns:

DestinationOrderQosPolicy reference

inline const DestinationOrderQosPolicy &destination_order() const

Getter for DestinationOrderQosPolicy

Returns:

DestinationOrderQosPolicy reference

inline void destination_order(const DestinationOrderQosPolicy &destination_order)

Setter for DestinationOrderQosPolicy

Parameters:

destination_order – new value for the DestinationOrderQosPolicy

inline HistoryQosPolicy &history()

Getter for HistoryQosPolicy

Returns:

HistoryQosPolicy reference

inline const HistoryQosPolicy &history() const

Getter for HistoryQosPolicy

Returns:

HistoryQosPolicy reference

inline void history(const HistoryQosPolicy &history)

Setter for HistoryQosPolicy

Parameters:

history – new value for the HistoryQosPolicy

inline ResourceLimitsQosPolicy &resource_limits()

Getter for ResourceLimitsQosPolicy

Returns:

ResourceLimitsQosPolicy reference

inline const ResourceLimitsQosPolicy &resource_limits() const

Getter for ResourceLimitsQosPolicy

Returns:

ResourceLimitsQosPolicy reference

inline void resource_limits(const ResourceLimitsQosPolicy &resource_limits)

Setter for ResourceLimitsQosPolicy

Parameters:

resource_limits – new value for the ResourceLimitsQosPolicy

inline TransportPriorityQosPolicy &transport_priority()

Getter for TransportPriorityQosPolicy

Returns:

TransportPriorityQosPolicy reference

inline const TransportPriorityQosPolicy &transport_priority() const

Getter for TransportPriorityQosPolicy

Returns:

TransportPriorityQosPolicy reference

inline void transport_priority(const TransportPriorityQosPolicy &transport_priority)

Setter for TransportPriorityQosPolicy

Parameters:

transport_priority – new value for the TransportPriorityQosPolicy

inline LifespanQosPolicy &lifespan()

Getter for LifespanQosPolicy

Returns:

LifespanQosPolicy reference

inline const LifespanQosPolicy &lifespan() const

Getter for LifespanQosPolicy

Returns:

LifespanQosPolicy reference

inline void lifespan(const LifespanQosPolicy &lifespan)

Setter for LifespanQosPolicy

Parameters:

lifespan – new value for the LifespanQosPolicy

inline UserDataQosPolicy &user_data()

Getter for UserDataQosPolicy

Returns:

UserDataQosPolicy reference

inline const UserDataQosPolicy &user_data() const

Getter for UserDataQosPolicy

Returns:

UserDataQosPolicy reference

inline void user_data(const UserDataQosPolicy &user_data)

Setter for UserDataQosPolicy

Parameters:

user_data – new value for the UserDataQosPolicy

inline OwnershipQosPolicy &ownership()

Getter for OwnershipQosPolicy

Returns:

OwnershipQosPolicy reference

inline const OwnershipQosPolicy &ownership() const

Getter for OwnershipQosPolicy

Returns:

OwnershipQosPolicy reference

inline void ownership(const OwnershipQosPolicy &ownership)

Setter for OwnershipQosPolicy

Parameters:

ownership – new value for the OwnershipQosPolicy

inline OwnershipStrengthQosPolicy &ownership_strength()

Getter for OwnershipStrengthQosPolicy

Returns:

OwnershipStrengthQosPolicy reference

inline const OwnershipStrengthQosPolicy &ownership_strength() const

Getter for OwnershipStrengthQosPolicy

Returns:

OwnershipStrengthQosPolicy reference

inline void ownership_strength(const OwnershipStrengthQosPolicy &ownership_strength)

Setter for OwnershipStrengthQosPolicy

Parameters:

ownership_strength – new value for the OwnershipStrengthQosPolicy

inline WriterDataLifecycleQosPolicy &writer_data_lifecycle()

Getter for WriterDataLifecycleQosPolicy

Returns:

WriterDataLifecycleQosPolicy reference

inline const WriterDataLifecycleQosPolicy &writer_data_lifecycle() const

Getter for WriterDataLifecycleQosPolicy

Returns:

WriterDataLifecycleQosPolicy reference

inline void writer_data_lifecycle(const WriterDataLifecycleQosPolicy &writer_data_lifecycle)

Setter for WriterDataLifecycleQosPolicy

Parameters:

writer_data_lifecycle – new value for the WriterDataLifecycleQosPolicy

inline PublishModeQosPolicy &publish_mode()

Getter for PublishModeQosPolicy

Returns:

PublishModeQosPolicy reference

inline const PublishModeQosPolicy &publish_mode() const

Getter for PublishModeQosPolicy

Returns:

PublishModeQosPolicy reference

inline void publish_mode(const PublishModeQosPolicy &publish_mode)

Setter for PublishModeQosPolicy

Parameters:

publish_mode – new value for the PublishModeQosPolicy

inline DataRepresentationQosPolicy &representation()

Getter for DataRepresentationQosPolicy

Returns:

DataRepresentationQosPolicy reference

inline const DataRepresentationQosPolicy &representation() const

Getter for DataRepresentationQosPolicy

Returns:

DataRepresentationQosPolicy reference

inline void representation(const DataRepresentationQosPolicy &representation)

Setter for DataRepresentationQosPolicy

Parameters:

representation – new value for the DataRepresentationQosPolicy

inline PropertyPolicyQos &properties()

Getter for PropertyPolicyQos

Returns:

PropertyPolicyQos reference

inline const PropertyPolicyQos &properties() const

Getter for PropertyPolicyQos

Returns:

PropertyPolicyQos reference

inline void properties(const PropertyPolicyQos &properties)

Setter for PropertyPolicyQos

Parameters:

properties – new value for the PropertyPolicyQos

inline RTPSReliableWriterQos &reliable_writer_qos()

Getter for RTPSReliableWriterQos

Returns:

RTPSReliableWriterQos reference

inline const RTPSReliableWriterQos &reliable_writer_qos() const

Getter for RTPSReliableWriterQos

Returns:

RTPSReliableWriterQos reference

inline void reliable_writer_qos(const RTPSReliableWriterQos &reliable_writer_qos)

Setter for RTPSReliableWriterQos

Parameters:

reliable_writer_qos – new value for the RTPSReliableWriterQos

inline RTPSEndpointQos &endpoint()

Getter for RTPSEndpointQos

Returns:

RTPSEndpointQos reference

inline const RTPSEndpointQos &endpoint() const

Getter for RTPSEndpointQos

Returns:

RTPSEndpointQos reference

inline void endpoint(const RTPSEndpointQos &endpoint)

Setter for RTPSEndpointQos

Parameters:

endpoint – new value for the RTPSEndpointQos

inline WriterResourceLimitsQos &writer_resource_limits()

Getter for WriterResourceLimitsQos

Returns:

WriterResourceLimitsQos reference

inline const WriterResourceLimitsQos &writer_resource_limits() const

Getter for WriterResourceLimitsQos

Returns:

WriterResourceLimitsQos reference

inline void writer_resource_limits(const WriterResourceLimitsQos &writer_resource_limits)

Setter for WriterResourceLimitsQos

Parameters:

writer_resource_limits – new value for the WriterResourceLimitsQos

inline DataSharingQosPolicy &data_sharing()

Getter for DataSharingQosPolicy

Returns:

DataSharingQosPolicy reference

inline const DataSharingQosPolicy &data_sharing() const

Getter for DataSharingQosPolicy

Returns:

DataSharingQosPolicy reference

inline void data_sharing(const DataSharingQosPolicy &data_sharing)

Setter for DataSharingQosPolicy

Parameters:

data_sharing – new value for the DataSharingQosPolicy

const DataWriterQos eprosima::fastdds::dds::DATAWRITER_QOS_DEFAULT
const DataWriterQos eprosima::fastdds::dds::DATAWRITER_QOS_USE_TOPIC_QOS
20.1.3.4. Publisher
class Publisher : public eprosima::fastdds::dds::DomainEntity

Class Publisher, used to send data to associated subscribers.

Public Functions

virtual ~Publisher()

Destructor.

virtual ReturnCode_t enable() override

This operation enables the Publisher.

Returns:

RETCODE_OK is successfully enabled. RETCODE_PRECONDITION_NOT_MET if the participant creating this Publisher is not enabled.

const PublisherQos &get_qos() const

Allows accessing the Publisher Qos.

Returns:

PublisherQos reference

ReturnCode_t get_qos(PublisherQos &qos) const

Retrieves the Publisher Qos.

Returns:

RETCODE_OK

ReturnCode_t set_qos(const PublisherQos &qos)

Allows modifying the Publisher Qos. The given Qos must be supported by the PublisherQos.

Parameters:

qosPublisherQos to be set

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const PublisherListener *get_listener() const

Retrieves the attached PublisherListener.

Returns:

PublisherListener pointer

ReturnCode_t set_listener(PublisherListener *listener)

Modifies the PublisherListener, sets the mask to StatusMask::all()

Parameters:

listener – new value for the PublisherListener

Returns:

RETCODE_OK

ReturnCode_t set_listener(PublisherListener *listener, const StatusMask &mask)

Modifies the PublisherListener.

Parameters:
Returns:

RETCODE_OK

DataWriter *create_datawriter(Topic *topic, const DataWriterQos &qos, DataWriterListener *listener = nullptr, const StatusMask &mask = StatusMask::all(), std::shared_ptr<fastdds::rtps::IPayloadPool> payload_pool = nullptr)

This operation creates a DataWriter. The returned DataWriter will be attached and belongs to the Publisher.

Parameters:
  • topicTopic the DataWriter will be listening

  • qos – QoS of the DataWriter.

  • listener – Pointer to the listener (default: nullptr).

  • maskStatusMask that holds statuses the listener responds to (default: all).

  • payload_pool – IPayloadPool shared pointer that defines writer payload (default: nullptr).

Returns:

Pointer to the created DataWriter. nullptr if failed.

DataWriter *create_datawriter_with_profile(Topic *topic, const std::string &profile_name, DataWriterListener *listener = nullptr, const StatusMask &mask = StatusMask::all(), std::shared_ptr<fastdds::rtps::IPayloadPool> payload_pool = nullptr)

This operation creates a DataWriter. The returned DataWriter will be attached and belongs to the Publisher.

Parameters:
  • topicTopic the DataWriter will be listening

  • profile_nameDataWriter profile name.

  • listener – Pointer to the listener (default: nullptr).

  • maskStatusMask that holds statuses the listener responds to (default: all).

  • payload_pool – IPayloadPool shared pointer that defines writer payload (default: nullptr).

Returns:

Pointer to the created DataWriter. nullptr if failed.

ReturnCode_t delete_datawriter(const DataWriter *writer)

This operation deletes a DataWriter that belongs to the Publisher.

The delete_datawriter operation must be called on the same Publisher object used to create the DataWriter. If delete_datawriter is called on a different Publisher, the operation will have no effect and it will return false.

The deletion of the DataWriter will automatically unregister all instances. Depending on the settings of the WRITER_DATA_LIFECYCLE QosPolicy, the deletion of the DataWriter may also dispose all instances.

Parameters:

writerDataWriter to delete

Returns:

RETCODE_PRECONDITION_NOT_MET if it does not belong to this Publisher, RETCODE_OK if it is correctly deleted and RETCODE_ERROR otherwise.

DataWriter *lookup_datawriter(const std::string &topic_name) const

This operation retrieves a previously created DataWriter belonging to the Publisher that is attached to a Topic with a matching topic_name. If no such DataWriter exists, the operation will return nullptr.

If multiple DataWriter attached to the Publisher satisfy this condition, then the operation will return one of them. It is not specified which one.

Parameters:

topic_name – Name of the Topic

Returns:

Pointer to a previously created DataWriter associated to a Topic with the requested topic_name

ReturnCode_t suspend_publications()

Indicates to FastDDS that the contained DataWriters are about to be modified.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Returns:

RETCODE_OK if successful, an error code otherwise

ReturnCode_t resume_publications()

Indicates to FastDDS that the modifications to the DataWriters are complete.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Returns:

RETCODE_OK if successful, an error code otherwise

ReturnCode_t begin_coherent_changes()

Signals the beginning of a set of coherent cache changes using the Datawriters attached to the publisher.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Returns:

RETCODE_OK if successful, an error code otherwise

ReturnCode_t end_coherent_changes()

Signals the end of a set of coherent cache changes.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Returns:

RETCODE_OK if successful, an error code otherwise

ReturnCode_t wait_for_acknowledgments(const fastdds::dds::Duration_t &max_wait)

This operation blocks the calling thread until either all data written by the reliable DataWriter entities is acknowledged by all matched reliable DataReader entities, or else the duration specified by the max_wait parameter elapses, whichever happens first. A return value of true indicates that all the samples written have been acknowledged by all reliable matched data readers; a return value of false indicates that max_wait elapsed before all the data was acknowledged.

Parameters:

max_wait – Maximum blocking time for this operation

Returns:

RETCODE_TIMEOUT if the function takes more than the maximum blocking time established, RETCODE_OK if the Publisher receives the acknowledgments and RETCODE_ERROR otherwise.

const DomainParticipant *get_participant() const

This operation returns the DomainParticipant to which the Publisher belongs.

Returns:

Pointer to the DomainParticipant

ReturnCode_t delete_contained_entities()

Deletes all contained DataWriters.

Returns:

RETCODE_OK if successful, an error code otherwise

ReturnCode_t set_default_datawriter_qos(const DataWriterQos &qos)

This operation sets a default value of the DataWriter QoS policies which will be used for newly created DataWriter entities in the case where the QoS policies are defaulted in the create_datawriter operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return false.

The special value DATAWRITER_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_datawriter_qos operation had never been called.

Parameters:

qosDataWriterQos to be set

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const DataWriterQos &get_default_datawriter_qos() const

This operation returns the default value of the DataWriter QoS, that is, the QoS policies which will be used for newly created DataWriter entities in the case where the QoS policies are defaulted in the create_datawriter operation.

The values retrieved by get_default_datawriter_qos will match the set of values specified on the last successful call to set_default_datawriter_qos, or else, if the call was never made, the default values.

Returns:

Current default WriterQos

ReturnCode_t get_default_datawriter_qos(DataWriterQos &qos) const

This operation retrieves the default value of the DataWriter QoS, that is, the QoS policies which will be used for newly created DataWriter entities in the case where the QoS policies are defaulted in the create_datawriter operation.

The values retrieved by get_default_datawriter_qos will match the set of values specified on the last successful call to set_default_datawriter_qos, or else, if the call was never made, the default values.

Parameters:

qos – Reference to the current default WriterQos.

Returns:

RETCODE_OK

ReturnCode_t get_datawriter_qos_from_profile(const std::string &profile_name, DataWriterQos &qos) const

Fills the DataWriterQos with the values of the XML profile.

Parameters:
Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datawriter_qos_from_profile(const std::string &profile_name, DataWriterQos &qos, std::string &topic_name) const

Fills the DataWriterQos with the values of the XML profile, and also its corresponding topic name (if specified).

Parameters:
  • profile_nameDataWriter profile name.

  • qosDataWriterQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datawriter_qos_from_xml(const std::string &xml, DataWriterQos &qos) const

Fills the DataWriterQos with the first DataWriter profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataWriterQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datawriter_qos_from_xml(const std::string &xml, DataWriterQos &qos, std::string &topic_name) const

Fills the DataWriterQos with the first DataWriter profile found in the provided XML, and also its corresponding topic name (if specified).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataWriterQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datawriter_qos_from_xml(const std::string &xml, DataWriterQos &qos, const std::string &profile_name) const

Fills the DataWriterQos with the DataWriter profile with profile_name to be found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataWriterQos object where the qos is returned.

  • profile_nameDataWriter profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datawriter_qos_from_xml(const std::string &xml, DataWriterQos &qos, std::string &topic_name, const std::string &profile_name) const

Fills the DataWriterQos with the DataWriter profile with profile_name to be found in the provided XML, and also its corresponding topic name (if specified).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataWriterQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

  • profile_nameDataWriter profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_datawriter_qos_from_xml(const std::string &xml, DataWriterQos &qos) const

Fills the DataWriterQos with the default DataWriter profile found in the provided XML (if there is).

Note

This method does not update the default datawriter qos (returned by get_default_datawriter_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataWriterQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_datawriter_qos_from_xml(const std::string &xml, DataWriterQos &qos, std::string &topic_name) const

Fills the DataWriterQos with the default DataWriter profile found in the provided XML (if there is), and also its corresponding topic name (if specified).

Note

This method does not update the default datawriter qos (returned by get_default_datawriter_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataWriterQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

const InstanceHandle_t &get_instance_handle() const

Returns the Publisher’s handle.

Returns:

InstanceHandle of this Publisher.

bool get_datawriters(std::vector<DataWriter*> &writers) const

Fills the given vector with all the datawriters of this publisher.

Parameters:

writers – Vector where the DataWriters are returned

Returns:

true

bool has_datawriters() const

This operation checks if the publisher has DataWriters

Returns:

true if the publisher has one or several DataWriters, false otherwise

Public Static Functions

static ReturnCode_t copy_from_topic_qos(fastdds::dds::DataWriterQos &writer_qos, const fastdds::dds::TopicQos &topic_qos)

Copies TopicQos into the corresponding DataWriterQos.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:
  • writer_qos[out]

  • topic_qos[in]

Returns:

RETCODE_OK if successful, an error code otherwise

20.1.3.5. PublisherListener
class PublisherListener : public eprosima::fastdds::dds::DataWriterListener

Class PublisherListener, allows the end user to implement callbacks triggered by certain events. It inherits all the DataWriterListener callbacks.

Subclassed by eprosima::fastdds::dds::DomainParticipantListener

Public Functions

inline PublisherListener()

Constructor.

inline virtual ~PublisherListener()

Destructor.

20.1.3.6. PublisherQos
class PublisherQos

Class PublisherQos, containing all the possible Qos that can be set for a determined Publisher. Although these values can be set and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

Public Functions

inline PublisherQos()

Constructor.

virtual ~PublisherQos() = default

Destructor.

inline const PresentationQosPolicy &presentation() const

Getter for PresentationQosPolicy

Returns:

PresentationQosPolicy reference

inline PresentationQosPolicy &presentation()

Getter for PresentationQosPolicy

Returns:

PresentationQosPolicy reference

inline void presentation(const PresentationQosPolicy &presentation)

Setter for PresentationQosPolicy

Parameters:

presentationPresentationQosPolicy

inline const PartitionQosPolicy &partition() const

Getter for PartitionQosPolicy

Returns:

PartitionQosPolicy reference

inline PartitionQosPolicy &partition()

Getter for PartitionQosPolicy

Returns:

PartitionQosPolicy reference

inline void partition(const PartitionQosPolicy &partition)

Setter for PartitionQosPolicy

Parameters:

partitionPartitionQosPolicy

inline const GroupDataQosPolicy &group_data() const

Getter for GroupDataQosPolicy

Returns:

GroupDataQosPolicy reference

inline GroupDataQosPolicy &group_data()

Getter for GroupDataQosPolicy

Returns:

GroupDataQosPolicy reference

inline void group_data(const GroupDataQosPolicy &group_data)

Setter for GroupDataQosPolicy

Parameters:

group_dataGroupDataQosPolicy

inline const EntityFactoryQosPolicy &entity_factory() const

Getter for EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference

inline EntityFactoryQosPolicy &entity_factory()

Getter for EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference

inline void entity_factory(const EntityFactoryQosPolicy &entity_factory)

Setter for EntityFactoryQosPolicy

Parameters:

entity_factoryEntityFactoryQosPolicy

const PublisherQos eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT
20.1.3.7. RTPSReliableWriterQos
class RTPSReliableWriterQos

Qos Policy to configure the DisablePositiveACKsQos and the writer timing attributes.

Public Functions

inline RTPSReliableWriterQos()

Constructor.

virtual ~RTPSReliableWriterQos() = default

Destructor.

Public Members

fastdds::rtps::WriterTimes times

Writer Timing Attributes.

DisablePositiveACKsQosPolicy disable_positive_acks

Disable positive acks QoS, implemented in the library.

bool disable_heartbeat_piggyback = false

Disable heartbeat piggyback mechanism.

20.1.4. Subscriber

20.1.4.1. DataReader
class DataReader : public eprosima::fastdds::dds::DomainEntity

Class DataReader, contains the actual implementation of the behaviour of the Subscriber.

Read or take data methods.

Methods to read or take data from the History.

ReturnCode_t read(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples = LENGTH_UNLIMITED, SampleStateMask sample_states = ANY_SAMPLE_STATE, ViewStateMask view_states = ANY_VIEW_STATE, InstanceStateMask instance_states = ANY_INSTANCE_STATE)

Access a collection of data samples from the DataReader.

This operation accesses a collection of Data values from the DataReader. The caller can limit the size of the returned collection with the max_samples parameter.

The properties of the data_values collection and the setting of the PresentationQosPolicy may impose further limits on the size of the returned ‘list.’

  1. If PresentationQosPolicy::access_scope is INSTANCE_PRESENTATION_QOS, then the returned collection is a ‘list’ where samples belonging to the same data-instance are consecutive.

  2. If PresentationQosPolicy::access_scope is TOPIC_PRESENTATION_QOS and PresentationQosPolicy::ordered_access is set to false, then the returned collection is a ‘list’ where samples belonging to the same data-instance are consecutive.

  3. If PresentationQosPolicy::access_scope is TOPIC_PRESENTATION_QOS and PresentationQosPolicy::ordered_access is set to true, then the returned collection is a ‘list’ where samples belonging to the same instance may or may not be consecutive. This is because to preserve order it may be necessary to mix samples from different instances.

  4. If PresentationQosPolicy::access_scope is GROUP_PRESENTATION_QOS and PresentationQosPolicy::ordered_access is set to false, then the returned collection is a ‘list’ where samples belonging to the same data instance are consecutive.

  5. If PresentationQosPolicy::access_scope is GROUP_PRESENTATION_QOS and PresentationQosPolicy::ordered_access is set to true, then the returned collection contains at most one sample. The difference in this case is due to the fact that it is required that the application is able to read samples belonging to different DataReader objects in a specific order.

In any case, the relative order between the samples of one instance is consistent with the DestinationOrderQosPolicy:

The actual number of samples returned depends on the information that has been received by the middleware as well as the HistoryQosPolicy, ResourceLimitsQosPolicy, and ReaderResourceLimitsQos:

If the operation succeeds and the number of samples returned has been limited (by means of a maximum limit, as listed above, or insufficient SampleInfo resources), the call will complete successfully and provide those samples the reader is able to return. The user may need to make additional calls, or return outstanding loaned buffers in the case of insufficient resources, in order to access remaining samples.

In addition to the collection of samples, the read operation also uses a collection of SampleInfo structures (sample_infos).

The initial (input) properties of the data_values and sample_infos collections will determine the precise behavior of this operation. For the purposes of this description the collections are modeled as having three properties:

The initial (input) values of the len, max_len, and owns properties for the data_values and sample_infos collections govern the behavior of the read operation as specified by the following rules:

  1. The values of len, max_len, and owns for the two collections must be identical. Otherwise read will fail with RETCODE_PRECONDITION_NOT_MET.

  2. On successful output, the values of len, max_len, and owns will be the same for both collections.

  3. If the input max_len == 0 , then the data_values and sample_infos collections will be filled with elements that are ‘loaned’ by the DataReader. On output, owns will be false, len will be set to the number of values returned, and max_len will be set to a value verifying max_len >= len . The use of this variant allows for zero-copy access to the data and the application will need to return the loan to the DataReader using the return_loan operation.

  4. If the input max_len > 0 and the input owns == false , then the read operation will fail with RETCODE_PRECONDITION_NOT_MET. This avoids the potential hard-to-detect memory leaks caused by an application forgetting to return the loan.

  5. If input max_len > 0 and the input owns == true , then the read operation will copy the Data values and SampleInfo values into the elements already inside the collections. On output, owns will be true, len will be set to the number of values copied, and max_len will remain unchanged. The use of this variant forces a copy but the application can control where the copy is placed and the application will not need to return the loan. The number of samples copied depends on the values of max_len and max_samples:

    • If max_samples == LENGTH_UNLIMITED , then at most max_len values will be copied. The use of this variant lets the application limit the number of samples returned to what the sequence can accommodate.

    • If max_samples <= max_len , then at most max_samples values will be copied. The use of this variant lets the application limit the number of samples returned to fewer that what the sequence can accommodate.

    • If max_samples > max_len , then the read operation will fail with RETCODE_PRECONDITION_NOT_MET. This avoids the potential confusion where the application expects to be able to access up to max_samples, but that number can never be returned, even if they are available in the DataReader, because the output sequence cannot accommodate them.

As described above, upon return the data_values and sample_infos collections may contain elements ‘loaned’ from the DataReader. If this is the case, the application will need to use the return_loan operation to return the loan once it is no longer using the Data in the collection. Upon return from return_loan, the collection will have max_len == 0 and owns == false .

The application can determine whether it is necessary to return the loan or not based on the state of the collections when the read operation was called, or by accessing the owns property. However, in many cases it may be simpler to always call return_loan, as this operation is harmless (i.e., leaves all elements unchanged) if the collection does not have a loan.

On output, the collection of Data values and the collection of SampleInfo structures are of the same length and are in a one-to-one correspondence. Each SampleInfo provides information, such as the source_timestamp, the sample_state, view_state, and instance_state, etc., about the corresponding sample.

Some elements in the returned collection may not have valid data. If the instance_state in the SampleInfo is NOT_ALIVE_DISPOSED_INSTANCE_STATE or NOT_ALIVE_NO_WRITERS_INSTANCE_STATE, then the last sample for that instance in the collection, that is, the one whose SampleInfo has sample_rank == 0 does not contain valid data. Samples that contain no data do not count towards the limits imposed by the ResourceLimitsQosPolicy.

The act of reading a sample changes its sample_state to READ_SAMPLE_STATE. If the sample belongs to the most recent generation of the instance, it will also set the view_state of the instance to be NOT_NEW_VIEW_STATE. It will not affect the instance_state of the instance.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Important: If the samples “returned” by this method are loaned from the middleware (see take for more information on memory loaning), it is important that their contents not be changed. Because the memory in which the data is stored belongs to the middleware, any modifications made to the data will be seen the next time the same samples are read or taken; the samples will no longer reflect the state that was received from the network.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are available, up to the limits described above.

  • sample_states[in] Only data samples with sample_state matching one of these will be returned.

  • view_states[in] Only data samples with view_state matching one of these will be returned.

  • instance_states[in] Only data samples with instance_state matching one of these will be returned.

Returns:

Any of the standard return codes.

ReturnCode_t read_w_condition(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples, ReadCondition *a_condition)

This operation accesses via ‘read’ the samples that match the criteria specified in the ReadCondition. This operation is especially useful in combination with QueryCondition to filter data samples based on the content.

The specified ReadCondition must be attached to the DataReader; otherwise the operation will fail and return RETCODE_PRECONDITION_NOT_MET.

In case the ReadCondition is a ‘plain’ ReadCondition and not the specialized QueryCondition, the operation is equivalent to calling read and passing as sample_states, view_states and instance_states the value of the corresponding attributes in a_condition. Using this operation the application can avoid repeating the same parameters specified when creating the ReadCondition.

The samples are accessed with the same semantics as the read operation. If the DataReader has no samples that meet the constraints, the return value will be RETCODE_NO_DATA.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned.

  • a_condition[in] A ReadCondition that returned data_values must pass

Returns:

Any of the standard return codes.

ReturnCode_t read_instance(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples = LENGTH_UNLIMITED, const InstanceHandle_t &a_handle = HANDLE_NIL, SampleStateMask sample_states = ANY_SAMPLE_STATE, ViewStateMask view_states = ANY_VIEW_STATE, InstanceStateMask instance_states = ANY_INSTANCE_STATE)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data values from the DataReader. The behavior is identical to read, except that all samples returned belong to the single specified instance whose handle is a_handle.

Upon successful completion, the data collection will contain samples all belonging to the same instance. The corresponding SampleInfo verifies SampleInfo::instance_handle == a_handle.

This operation is semantically equivalent to the read operation, except in building the collection. The DataReader will check that the sample belongs to the specified instance and otherwise it will not place the sample in the returned collection.

The behavior of this operation follows the same rules as the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos. Similar to read, this operation may ‘loan’ elements to the output collections, which must then be returned by means of return_loan.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are available, up to the limits described in the documentation for read().

  • a_handle[in] The specified instance to return samples for. The method will fail with RETCODE_BAD_PARAMETER if the handle does not correspond to an existing data-object known to the DataReader.

  • sample_states[in] Only data samples with sample_state matching one of these will be returned.

  • view_states[in] Only data samples with view_state matching one of these will be returned.

  • instance_states[in] Only data samples with instance_state matching one of these will be returned.

Returns:

Any of the standard return codes.

ReturnCode_t read_next_instance(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples = LENGTH_UNLIMITED, const InstanceHandle_t &previous_handle = HANDLE_NIL, SampleStateMask sample_states = ANY_SAMPLE_STATE, ViewStateMask view_states = ANY_VIEW_STATE, InstanceStateMask instance_states = ANY_INSTANCE_STATE)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data values from the DataReader where all the samples belong to a single instance. The behavior is similar to read_instance, except that the actual instance is not directly specified. Rather, the samples will all belong to the ‘next’ instance with instance_handle ‘greater’ than the specified ‘previous_handle’ that has available samples.

This operation implies the existence of a total order ‘greater-than’ relationship between the instance handles. The specifics of this relationship are not all important and are implementation specific. The important thing is that, according to the middleware, all instances are ordered relative to each other. This ordering is between the instance handles, and should not depend on the state of the instance (e.g. whether it has data or not) and must be defined even for instance handles that do not correspond to instances currently managed by the DataReader. For the purposes of the ordering, it should be ‘as if’ each instance handle was represented as an integer.

The behavior of this operation is ‘as if’ the DataReader invoked read_instance, passing the smallest instance_handle among all the ones that: (a) are greater than previous_handle, and (b) have available samples (i.e. samples that meet the constraints imposed by the specified states).

The special value HANDLE_NIL is guaranteed to be ‘less than’ any valid instance_handle. So the use of the parameter value previous_handle == HANDLE_NIL will return the samples for the instance which has the smallest instance_handle among all the instances that contain available samples.

This operation is intended to be used in an application-driven iteration, where the application starts by passing previous_handle == HANDLE_NIL, examines the samples returned, and then uses the instance_handle returned in the SampleInfo as the value of the previous_handle argument to the next call to read_next_instance. The iteration continues until read_next_instance fails with RETCODE_NO_DATA.

Note that it is possible to call the read_next_instance operation with a previous_handle that does not correspond to an instance currently managed by the DataReader. This is because as stated earlier the ‘greater-than’ relationship is defined even for handles not managed by the DataReader. One practical situation where this may occur is when an application is iterating through all the instances, takes all the samples of a NOT_ALIVE_NO_WRITERS_INSTANCE_STATE instance, returns the loan (at which point the instance information may be removed, and thus the handle becomes invalid), and tries to read the next instance.

The behavior of this operation follows the same rules as the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos. Similar to read, this operation may ‘loan’ elements to the output collections, which must then be returned by means of return_loan.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are available, up to the limits described in the documentation for read().

  • previous_handle[in] The ‘next smallest’ instance with a value greater than this value that has available samples will be returned.

  • sample_states[in] Only data samples with sample_state matching one of these will be returned.

  • view_states[in] Only data samples with view_state matching one of these will be returned.

  • instance_states[in] Only data samples with instance_state matching one of these will be returned.

Returns:

Any of the standard return codes.

ReturnCode_t read_next_instance_w_condition(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples, const InstanceHandle_t &previous_handle, ReadCondition *a_condition)

This operation accesses a collection of Data values from the DataReader. The behavior is identical to read_next_instance except that all samples returned satisfy the specified condition. In other words, on success all returned samples belong to the same instance, and the instance is the instance with ‘smallest’ instance_handle among the ones that verify (a) instance_handle >= previous_handle and (b) have samples for which the specified ReadCondition evaluates to TRUE.

Similar to the operation read_next_instance it is possible to call read_next_instance_w_condition with a previous_handle that does not correspond to an instance currently managed by the DataReader.

The behavior of the read_next_instance_w_condition operation follows the same rules than the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos collections. Similar to read, the read_next_instance_w_condition operation may ‘loan’ elements to the output collections which must then be returned by means of return_loan.

If the DataReader has no samples that meet the constraints, the return value will be RETCODE_NO_DATA.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are available, up to the limits described in the documentation for read().

  • previous_handle[in] The ‘next smallest’ instance with a value greater than this value that has available samples will be returned.

  • a_condition[in] A ReadCondition that returned data_values must pass

Returns:

Any of the standard return codes.

ReturnCode_t read_next_sample(void *data, SampleInfo *info)

This operation copies the next, non-previously accessed Data value from the DataReader; the operation also copies the corresponding SampleInfo. The implied order among the samples stored in the DataReader is the same as for the read operation.

The read_next_sample operation is semantically equivalent to the read operation where the input Data sequence has max_length = 1 , the sample_states = NOT_READ_SAMPLE_STATE , the view_states = ANY_VIEW_STATE , and the instance_states = ANY_INSTANCE_STATE .

The read_next_sample operation provides a simplified API to ‘read’ samples avoiding the need for the application to manage sequences and specify states.

If there is no unread data in the DataReader, the operation will return RETCODE_NO_DATA and nothing is copied

Parameters:
  • data[out] Data pointer to store the sample

  • info[out] SampleInfo pointer to store the sample information

Returns:

Any of the standard return codes.

ReturnCode_t take(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples = LENGTH_UNLIMITED, SampleStateMask sample_states = ANY_SAMPLE_STATE, ViewStateMask view_states = ANY_VIEW_STATE, InstanceStateMask instance_states = ANY_INSTANCE_STATE)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data-samples from the DataReader and a corresponding collection of SampleInfo structures, and ‘removes’ them from the DataReader. The operation will return either a ‘list’ of samples or else a single sample. This is controlled by the PresentationQosPolicy using the same logic as for the read operation.

The act of taking a sample removes it from the DataReader so it cannot be ‘read’ or ‘taken’ again. If the sample belongs to the most recent generation of the instance, it will also set the view_state of the instance to NOT_NEW. It will not affect the instance_state of the instance.

The behavior of the take operation follows the same rules than the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos collections. Similar to read, the take operation may ‘loan’ elements to the output collections which must then be returned by means of return_loan. The only difference with read is that, as stated, the samples returned by take will no longer be accessible to successive calls to read or take.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are available, up to the limits described in the documentation for read().

  • sample_states[in] Only data samples with sample_state matching one of these will be returned.

  • view_states[in] Only data samples with view_state matching one of these will be returned.

  • instance_states[in] Only data samples with instance_state matching one of these will be returned.

Returns:

Any of the standard return codes.

ReturnCode_t take_w_condition(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples, ReadCondition *a_condition)

This operation is analogous to read_w_condition except it accesses samples via the ‘take’ operation.

The specified ReadCondition must be attached to the DataReader; otherwise the operation will fail and return RETCODE_PRECONDITION_NOT_MET.

The samples are accessed with the same semantics as the take operation.

This operation is especially useful in combination with QueryCondition to filter data samples based on the content.

If the DataReader has no samples that meet the constraints, the return value will be RETCODE_NO_DATA.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are.

  • a_condition[in] A ReadCondition that returned data_values must pass

Returns:

Any of the standard return codes.

ReturnCode_t take_instance(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples = LENGTH_UNLIMITED, const InstanceHandle_t &a_handle = HANDLE_NIL, SampleStateMask sample_states = ANY_SAMPLE_STATE, ViewStateMask view_states = ANY_VIEW_STATE, InstanceStateMask instance_states = ANY_INSTANCE_STATE)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data values from the DataReader and ‘removes’ them from the DataReader.

This operation has the same behavior as read_instance, except that the samples are ‘taken’ from the DataReader such that they are no longer accessible via subsequent ‘read’ or ‘take’ operations.

The behavior of this operation follows the same rules as the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos. Similar to read, this operation may ‘loan’ elements to the output collections, which must then be returned by means of return_loan.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are available, up to the limits described in the documentation for read().

  • a_handle[in] The specified instance to return samples for. The method will fail with RETCODE_BAD_PARAMETER if the handle does not correspond to an existing data-object known to the DataReader.

  • sample_states[in] Only data samples with sample_state matching one of these will be returned.

  • view_states[in] Only data samples with view_state matching one of these will be returned.

  • instance_states[in] Only data samples with instance_state matching one of these will be returned.

Returns:

Any of the standard return codes.

ReturnCode_t take_next_instance(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples = LENGTH_UNLIMITED, const InstanceHandle_t &previous_handle = HANDLE_NIL, SampleStateMask sample_states = ANY_SAMPLE_STATE, ViewStateMask view_states = ANY_VIEW_STATE, InstanceStateMask instance_states = ANY_INSTANCE_STATE)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data values from the DataReader and ‘removes’ them from the DataReader.

This operation has the same behavior as read_next_instance, except that the samples are ‘taken’ from the DataReader such that they are no longer accessible via subsequent ‘read’ or ‘take’ operations.

Similar to the operation read_next_instance, it is possible to call this operation with a previous_handle that does not correspond to an instance currently managed by the DataReader.

The behavior of this operation follows the same rules as the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos. Similar to read, this operation may ‘loan’ elements to the output collections, which must then be returned by means of return_loan.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are available, up to the limits described in the documentation for read().

  • previous_handle[in] The ‘next smallest’ instance with a value greater than this value that has available samples will be returned.

  • sample_states[in] Only data samples with sample_state matching one of these will be returned.

  • view_states[in] Only data samples with view_state matching one of these will be returned.

  • instance_states[in] Only data samples with instance_state matching one of these will be returned.

Returns:

Any of the standard return codes.

ReturnCode_t take_next_instance_w_condition(LoanableCollection &data_values, SampleInfoSeq &sample_infos, int32_t max_samples, const InstanceHandle_t &previous_handle, ReadCondition *a_condition)

This operation accesses a collection of Data values from the DataReader. The behavior is identical to read_next_instance except that all samples returned satisfy the specified condition. In other words, on success all returned samples belong to the same instance, and the instance is the instance with ‘smallest’ instance_handle among the ones that verify (a) instance_handle >= previous_handle and (b) have samples for which the specified ReadCondition evaluates to TRUE.

Similar to the operation read_next_instance it is possible to call read_next_instance_w_condition with a previous_handle that does not correspond to an instance currently managed by the DataReader.

The behavior of the read_next_instance_w_condition operation follows the same rules than the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos collections. Similar to read, the read_next_instance_w_condition operation may ‘loan’ elements to the output collections which must then be returned by means of return_loan.

If the DataReader has no samples that meet the constraints, the return value will be RETCODE_NO_DATA

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples will be returned.

  • sample_infos[inout] A SampleInfoSeq object where the received sample info will be returned.

  • max_samples[in] The maximum number of samples to be returned. If the special value LENGTH_UNLIMITED is provided, as many samples will be returned as are available, up to the limits described in the documentation for read().

  • previous_handle[in] The ‘next smallest’ instance with a value greater than this value that has available samples will be returned.

  • a_condition[in] A ReadCondition that returned data_values must pass

Returns:

Any of the standard return codes.

ReturnCode_t take_next_sample(void *data, SampleInfo *info)

This operation copies the next, non-previously accessed Data value from the DataReader and ‘removes’ it from the DataReader so it is no longer accessible. The operation also copies the corresponding SampleInfo.

This operation is analogous to read_next_sample except for the fact that the sample is ‘removed’ from the DataReader.

This operation is semantically equivalent to the take operation where the input sequence has max_length = 1 , the sample_states = NOT_READ_SAMPLE_STATE , the view_states = ANY_VIEW_STATE , and the instance_states = ANY_INSTANCE_STATE .

This operation provides a simplified API to ’take’ samples avoiding the need for the application to manage sequences and specify states.

If there is no unread data in the DataReader, the operation will return RETCODE_NO_DATA and nothing is copied.

Parameters:
  • data[out] Data pointer to store the sample

  • info[out] SampleInfo pointer to store the sample information

Returns:

Any of the standard return codes.

Public Functions

virtual ~DataReader()

Destructor.

virtual ReturnCode_t enable() override

This operation enables the DataReader.

Returns:

RETCODE_OK is successfully enabled. RETCODE_PRECONDITION_NOT_MET if the Subscriber creating this DataReader is not enabled.

bool wait_for_unread_message(const fastdds::dds::Duration_t &timeout)

Method to block the current thread until an unread message is available.

Parameters:

timeout[in] Max blocking time for this operation.

Returns:

true if there is new unread message, false if timeout

ReturnCode_t wait_for_historical_data(const fastdds::dds::Duration_t &max_wait) const

Method to block the current thread until an unread message is available.

NOT YET IMPLEMENTED

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

max_wait[in] Max blocking time for this operation.

Returns:

RETCODE_OK if there is new unread message, RETCODE_TIMEOUT if timeout

ReturnCode_t return_loan(LoanableCollection &data_values, SampleInfoSeq &sample_infos)

This operation indicates to the DataReader that the application is done accessing the collection of data_values and sample_infos obtained by some earlier invocation of read or take on the DataReader.

The data_values and sample_infos must belong to a single related ‘pair’; that is, they should correspond to a pair returned from a single call to read or take. The data_values and sample_infos must also have been obtained from the same DataReader to which they are returned. If either of these conditions is not met, the operation will fail and return RETCODE_PRECONDITION_NOT_MET.

This operation allows implementations of the read and take operations to “loan” buffers from the DataReader to the application and in this manner provide “zero-copy” access to the data. During the loan, the DataReader will guarantee that the data and sample-information are not modified.

It is not necessary for an application to return the loans immediately after the read or take calls. However, as these buffers correspond to internal resources inside the DataReader, the application should not retain them indefinitely.

The use of the return_loan operation is only necessary if the read or take calls “loaned” buffers to the application. This only occurs if the data_values and sample_infos collections had max_len == 0 at the time read or take was called. The application may also examine the has_ownership property of the collection to determine if there is an outstanding loan. However, calling return_loan on a collection that does not have a loan is safe, has no side effects, and returns RETCODE_OK.

If the collections had a loan, upon return from return_loan the collections will have max_len == 0 .

Parameters:
  • data_values[inout] A LoanableCollection object where the received data samples were obtained from an earlier invocation of read or take on this DataReader.

  • sample_infos[inout] A SampleInfoSeq object where the received sample infos were obtained from an earlier invocation of read or take on this DataReader.

Returns:

Any of the standard return codes.

ReturnCode_t get_key_value(void *key_holder, const InstanceHandle_t &handle)

NOT YET IMPLEMENTED

This operation can be used to retrieve the instance key that corresponds to an instance_handle. The operation will only fill the fields that form the key inside the key_holder instance.

This operation may return BAD_PARAMETER if the InstanceHandle_t a_handle does not correspond to an existing data-object known to the DataReader. If the implementation is not able to check invalid handles then the result in this situation is unspecified.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:
  • key_holder[inout]

  • handle[in]

Returns:

Any of the standard return codes.

InstanceHandle_t lookup_instance(const void *instance) const

Takes as a parameter an instance and returns a handle that can be used in subsequent operations that accept an instance handle as an argument. The instance parameter is only used for the purpose of examining the fields that define the key.

Parameters:

instance[in] Data pointer to the sample

Returns:

handle of the given instance.

Returns:

HANDLE_NIL if instance is nullptr.

Returns:

HANDLE_NIL if there is no instance on the DataReader’s history with the same key as instance.

ReturnCode_t get_first_untaken_info(SampleInfo *info)

Returns information about the first untaken sample. This method is meant to be called prior to a read() or take() operation as it does not modify the status condition of the entity.

Parameters:

info[out] Pointer to a SampleInfo_t structure to store first untaken sample information.

Returns:

RETCODE_OK if sample info was returned. RETCODE_NO_DATA if there is no sample to take.

uint64_t get_unread_count() const

Get the number of samples pending to be read. The number includes samples that may not yet be available to be read or taken by the user, due to samples being received out of order.

Returns:

the number of samples on the reader history that have never been read.

uint64_t get_unread_count(bool mark_as_read) const

Get the number of samples pending to be read.

Parameters:

mark_as_read – Whether the unread samples should be marked as read or not.

Returns:

the number of samples on the reader history that have never been read.

const fastdds::rtps::GUID_t &guid()

Get associated GUID.

Returns:

Associated GUID

const fastdds::rtps::GUID_t &guid() const

Get associated GUID.

Returns:

Associated GUID

InstanceHandle_t get_instance_handle() const

Getter for the associated InstanceHandle.

Returns:

Copy of the InstanceHandle

TypeSupport type() const

Getter for the data type.

Returns:

Copy of the TypeSupport associated to the DataReader.

const TopicDescription *get_topicdescription() const

Get TopicDescription.

Returns:

TopicDescription pointer.

ReturnCode_t get_requested_deadline_missed_status(RequestedDeadlineMissedStatus &status)

Get the requested deadline missed status.

Returns:

The deadline missed status.

ReturnCode_t get_requested_incompatible_qos_status(RequestedIncompatibleQosStatus &status)

Get the requested incompatible qos status.

Parameters:

status[out] Requested incompatible qos status.

Returns:

RETCODE_OK

ReturnCode_t set_qos(const DataReaderQos &qos)

Setter for the DataReaderQos.

Parameters:

qos[in] new value for the DataReaderQos.

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const DataReaderQos &get_qos() const

Getter for the DataReaderQos.

Returns:

Pointer to the DataReaderQos.

ReturnCode_t get_qos(DataReaderQos &qos) const

Getter for the DataReaderQos.

Parameters:

qos[in] DataReaderQos where the qos is returned.

Returns:

RETCODE_OK

ReturnCode_t set_listener(DataReaderListener *listener)

Modifies the DataReaderListener, sets the mask to StatusMask::all().

Parameters:

listener[in] new value for the DataReaderListener.

Returns:

RETCODE_OK

ReturnCode_t set_listener(DataReaderListener *listener, const StatusMask &mask)

Modifies the DataReaderListener.

Parameters:
  • listener[in] new value for the DataReaderListener.

  • mask[in] StatusMask that holds statuses the listener responds to (default: all).

Returns:

RETCODE_OK

const DataReaderListener *get_listener() const

Getter for the DataReaderListener.

Returns:

Pointer to the DataReaderListener

ReturnCode_t get_liveliness_changed_status(LivelinessChangedStatus &status) const

Get the liveliness changed status.

Parameters:

status[out] LivelinessChangedStatus object where the status is returned.

Returns:

RETCODE_OK

ReturnCode_t get_sample_lost_status(SampleLostStatus &status) const

Get the SAMPLE_LOST communication status.

Parameters:

status[out] SampleLostStatus object where the status is returned.

Returns:

RETCODE_OK

ReturnCode_t get_sample_rejected_status(SampleRejectedStatus &status) const

Get the SAMPLE_REJECTED communication status.

Parameters:

status[out] SampleRejectedStatus object where the status is returned.

Returns:

RETCODE_OK

ReturnCode_t get_subscription_matched_status(SubscriptionMatchedStatus &status) const

Returns the subscription matched status.

Parameters:

status[out] subscription matched status struct

Returns:

RETCODE_OK

ReturnCode_t get_matched_publication_data(PublicationBuiltinTopicData &publication_data, const fastdds::rtps::InstanceHandle_t &publication_handle) const

Retrieves in a publication associated with the DataWriter.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:
  • publication_data[out] publication data struct

  • publication_handle – InstanceHandle_t of the publication

Returns:

RETCODE_OK

ReturnCode_t get_matched_publications(std::vector<InstanceHandle_t> &publication_handles) const

Fills the given vector with the InstanceHandle_t of matched DataReaders.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

publication_handles[out] Vector where the InstanceHandle_t are returned

Returns:

RETCODE_OK

ReadCondition *create_readcondition(SampleStateMask sample_states, ViewStateMask view_states, InstanceStateMask instance_states)

This operation creates a ReadCondition. The returned ReadCondition will be attached and belong to the DataReader.

Parameters:
  • sample_states[in] Only data samples with sample_state matching one of these will trigger the created condition.

  • view_states[in] Only data samples with view_state matching one of these will trigger the created condition.

  • instance_states[in] Only data samples with instance_state matching one of these will trigger the created condition.

Returns:

pointer to the created ReadCondition, nullptr in case of error.

QueryCondition *create_querycondition(SampleStateMask sample_states, ViewStateMask view_states, InstanceStateMask instance_states, const std::string &query_expression, const std::vector<std::string> &query_parameters)

This operation creates a QueryCondition. The returned QueryCondition will be attached and belong to the DataReader.

Parameters:
  • sample_states[in] Only data samples with sample_state matching one of these will trigger the created condition.

  • view_states[in] Only data samples with view_state matching one of these will trigger the created condition.

  • instance_states[in] Only data samples with instance_state matching one of these will trigger the created condition.

  • query_expression[in] Only data samples matching this query will trigger the created condition.

  • query_parameters[in] Value of the parameters on the query expression.

Returns:

pointer to the created QueryCondition, nullptr in case of error.

ReturnCode_t delete_readcondition(ReadCondition *a_condition)

This operation deletes a ReadCondition attached to the DataReader.

Parameters:

a_condition – pointer to a ReadCondition belonging to the DataReader

Returns:

RETCODE_OK

const Subscriber *get_subscriber() const

Getter for the Subscriber.

Returns:

Subscriber pointer

ReturnCode_t delete_contained_entities()

This operation deletes all the entities that were created by means of the “create” operations on the DataReader. That is, it deletes all contained ReadCondition and QueryCondition objects.

The operation will return PRECONDITION_NOT_MET if the any of the contained entities is in a state where it cannot be deleted.

Returns:

Any of the standard return codes.

bool is_sample_valid(const void *data, const SampleInfo *info) const

Checks whether a loaned sample is still valid or is corrupted. Calling this method on a sample which has not been loaned, or one for which the loan has been returned yields undefined behavior.

Parameters:
  • data – Pointer to the sample data to check

  • info – Pointer to the SampleInfo related to data

Returns:

true if the sample is valid

ReturnCode_t get_listening_locators(rtps::LocatorList &locators) const

Get the list of locators on which this DataReader is listening.

Parameters:

locators[out] LocatorList where the list of locators will be stored.

Returns:

NOT_ENABLED if the reader has not been enabled.

Returns:

OK if a list of locators is returned.

ReturnCode_t get_subscription_builtin_topic_data(SubscriptionBuiltinTopicData &subscription_data) const

Retrieve the subscription data discovery information.

Parameters:

subscription_data[out] The subscription data discovery information.

Returns:

NOT_ENABLED if the reader has not been enabled.

Returns:

OK if the subscription data is returned.

20.1.4.2. DataReaderListener
class DataReaderListener

Class DataReaderListener, it should be used by the end user to implement specific callbacks to certain actions.

Subclassed by eprosima::fastdds::dds::SubscriberListener

Public Functions

inline DataReaderListener()

Constructor.

inline virtual ~DataReaderListener()

Destructor.

inline virtual void on_data_available(DataReader *reader)

Virtual function to be implemented by the user containing the actions to be performed when new Data Messages are received.

Parameters:

readerDataReader

inline virtual void on_subscription_matched(DataReader *reader, const fastdds::dds::SubscriptionMatchedStatus &info)

Virtual method to be called when the subscriber is matched with a new Writer (or unmatched); i.e., when a writer publishing in the same topic is discovered.

Parameters:
  • readerDataReader

  • info – The subscription matched status

inline virtual void on_requested_deadline_missed(DataReader *reader, const RequestedDeadlineMissedStatus &status)

Virtual method to be called when a topic misses the deadline period

Parameters:
  • readerDataReader

  • status – The requested deadline missed status

inline virtual void on_liveliness_changed(DataReader *reader, const LivelinessChangedStatus &status)

Method called when the liveliness status associated to a subscriber changes.

Parameters:
  • reader – The DataReader

  • status – The liveliness changed status

inline virtual void on_sample_rejected(DataReader *reader, const SampleRejectedStatus &status)

Method called when a sample was rejected.

Parameters:
  • reader – The DataReader

  • status – The rejected status

inline virtual void on_requested_incompatible_qos(DataReader *reader, const RequestedIncompatibleQosStatus &status)

Method called an incompatible QoS was requested.

Parameters:
  • reader – The DataReader

  • status – The requested incompatible QoS status

inline virtual void on_sample_lost(DataReader *reader, const SampleLostStatus &status)

Method called when a sample was lost.

Parameters:
  • reader – The DataReader

  • status – The sample lost status

20.1.4.3. DataReaderQos
class DataReaderQos

Class DataReaderQos, containing all the possible Qos that can be set for a determined DataReader. Although these values can be set and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

Subclassed by eprosima::fastdds::statistics::dds::DataReaderQos, eprosima::fastdds::statistics::dds::MonitorServiceDataReaderQos

Public Functions

inline DataReaderQos()

Constructor.

inline DurabilityQosPolicy &durability()

Getter for DurabilityQosPolicy

Returns:

DurabilityQosPolicy reference

inline const DurabilityQosPolicy &durability() const

Getter for DurabilityQosPolicy

Returns:

DurabilityQosPolicy const reference

inline void durability(const DurabilityQosPolicy &new_value)

Setter for DurabilityQosPolicy

Parameters:

new_value – new value for the DurabilityQosPolicy

inline DeadlineQosPolicy &deadline()

Getter for DeadlineQosPolicy

Returns:

DeadlineQosPolicy reference

inline const DeadlineQosPolicy &deadline() const

Getter for DeadlineQosPolicy

Returns:

DeadlineQosPolicy const reference

inline void deadline(const DeadlineQosPolicy &new_value)

Setter for DeadlineQosPolicy

Parameters:

new_value – new value for the DeadlineQosPolicy

inline LatencyBudgetQosPolicy &latency_budget()

Getter for LatencyBudgetQosPolicy

Returns:

LatencyBudgetQosPolicy reference

inline const LatencyBudgetQosPolicy &latency_budget() const

Getter for LatencyBudgetQosPolicy

Returns:

LatencyBudgetQosPolicy const reference

inline void latency_budget(const LatencyBudgetQosPolicy &new_value)

Setter for LatencyBudgetQosPolicy

Parameters:

new_value – new value for the LatencyBudgetQosPolicy

inline LivelinessQosPolicy &liveliness()

Getter for LivelinessQosPolicy

Returns:

LivelinessQosPolicy reference

inline const LivelinessQosPolicy &liveliness() const

Getter for LivelinessQosPolicy

Returns:

LivelinessQosPolicy const reference

inline void liveliness(const LivelinessQosPolicy &new_value)

Setter for LivelinessQosPolicy

Parameters:

new_value – new value for the LivelinessQosPolicy

inline ReliabilityQosPolicy &reliability()

Getter for ReliabilityQosPolicy

Returns:

ReliabilityQosPolicy reference

inline const ReliabilityQosPolicy &reliability() const

Getter for ReliabilityQosPolicy

Returns:

ReliabilityQosPolicy const reference

inline void reliability(const ReliabilityQosPolicy &new_value)

Setter for ReliabilityQosPolicy

Parameters:

new_value – new value for the ReliabilityQosPolicy

inline DestinationOrderQosPolicy &destination_order()

Getter for DestinationOrderQosPolicy

Returns:

DestinationOrderQosPolicy reference

inline const DestinationOrderQosPolicy &destination_order() const

Getter for DestinationOrderQosPolicy

Returns:

DestinationOrderQosPolicy const reference

inline void destination_order(const DestinationOrderQosPolicy &new_value)

Setter for DestinationOrderQosPolicy

Parameters:

new_value – new value for the DestinationOrderQosPolicy

inline HistoryQosPolicy &history()

Getter for HistoryQosPolicy

Returns:

HistoryQosPolicy reference

inline const HistoryQosPolicy &history() const

Getter for HistoryQosPolicy

Returns:

HistoryQosPolicy const reference

inline void history(const HistoryQosPolicy &new_value)

Setter for HistoryQosPolicy

Parameters:

new_value – new value for the HistoryQosPolicy

inline ResourceLimitsQosPolicy &resource_limits()

Getter for ResourceLimitsQosPolicy

Returns:

ResourceLimitsQosPolicy reference

inline const ResourceLimitsQosPolicy &resource_limits() const

Getter for ResourceLimitsQosPolicy

Returns:

ResourceLimitsQosPolicy const reference

inline void resource_limits(const ResourceLimitsQosPolicy &new_value)

Setter for ResourceLimitsQosPolicy

Parameters:

new_value – new value for the ResourceLimitsQosPolicy

inline UserDataQosPolicy &user_data()

Getter for UserDataQosPolicy

Returns:

UserDataQosPolicy reference

inline const UserDataQosPolicy &user_data() const

Getter for UserDataQosPolicy

Returns:

UserDataQosPolicy const reference

inline void user_data(const UserDataQosPolicy &new_value)

Setter for UserDataQosPolicy

Parameters:

new_value – new value for the UserDataQosPolicy

inline OwnershipQosPolicy &ownership()

Getter for OwnershipQosPolicy

Returns:

OwnershipQosPolicy reference

inline const OwnershipQosPolicy &ownership() const

Getter for OwnershipQosPolicy

Returns:

OwnershipQosPolicy const reference

inline void ownership(const OwnershipQosPolicy &new_value)

Setter for OwnershipQosPolicy

Parameters:

new_value – new value for the OwnershipQosPolicy

inline TimeBasedFilterQosPolicy &time_based_filter()

Getter for TimeBasedFilterQosPolicy

Returns:

TimeBasedFilterQosPolicy reference

inline const TimeBasedFilterQosPolicy &time_based_filter() const

Getter for TimeBasedFilterQosPolicy

Returns:

TimeBasedFilterQosPolicy const reference

inline void time_based_filter(const TimeBasedFilterQosPolicy &new_value)

Setter for TimeBasedFilterQosPolicy

Parameters:

new_value – new value for the TimeBasedFilterQosPolicy

inline ReaderDataLifecycleQosPolicy &reader_data_lifecycle()

Getter for ReaderDataLifecycleQosPolicy

Returns:

ReaderDataLifecycleQosPolicy reference

inline const ReaderDataLifecycleQosPolicy &reader_data_lifecycle() const

Getter for ReaderDataLifecycleQosPolicy

Returns:

ReaderDataLifecycleQosPolicy const reference

inline void reader_data_lifecycle(const ReaderDataLifecycleQosPolicy &new_value)

Setter for ReaderDataLifecycleQosPolicy

Parameters:

new_value – new value for the ReaderDataLifecycleQosPolicy

inline LifespanQosPolicy &lifespan()

Getter for LifespanQosPolicy

Returns:

LifespanQosPolicy reference

inline const LifespanQosPolicy &lifespan() const

Getter for LifespanQosPolicy

Returns:

LifespanQosPolicy const reference

inline void lifespan(const LifespanQosPolicy &new_value)

Setter for LifespanQosPolicy

Parameters:

new_value – new value for the LifespanQosPolicy

inline DurabilityServiceQosPolicy &durability_service()

Getter for DurabilityServiceQosPolicy

Returns:

DurabilityServiceQosPolicy reference

inline const DurabilityServiceQosPolicy &durability_service() const

Getter for DurabilityServiceQosPolicy

Returns:

DurabilityServiceQosPolicy const reference

inline void durability_service(const DurabilityServiceQosPolicy &new_value)

Setter for DurabilityServiceQosPolicy

Parameters:

new_value – new value for the DurabilityServiceQosPolicy

inline RTPSReliableReaderQos &reliable_reader_qos()

Getter for RTPSReliableReaderQos

Returns:

RTPSReliableReaderQos reference

inline const RTPSReliableReaderQos &reliable_reader_qos() const

Getter for RTPSReliableReaderQos

Returns:

RTPSReliableReaderQos const reference

inline void reliable_reader_qos(const RTPSReliableReaderQos &new_value)

Setter for RTPSReliableReaderQos

Parameters:

new_value – new value for the RTPSReliableReaderQos

inline TypeConsistencyEnforcementQosPolicy &type_consistency()

Getter for TypeConsistencyEnforcementQosPolicy

Returns:

TypeConsistencyEnforcementQosPolicy reference

inline const TypeConsistencyEnforcementQosPolicy &type_consistency() const

Getter for TypeConsistencyEnforcementQosPolicy

Returns:

TypeConsistencyEnforcementQosPolicy const reference

inline void type_consistency(const TypeConsistencyEnforcementQosPolicy &new_value)

Setter for TypeConsistencyEnforcementQosPolicy

Parameters:

new_value – new value for the TypeConsistencyEnforcementQosPolicy

inline const DataRepresentationQosPolicy &representation() const

Getter for DataRepresentationQosPolicy

Returns:

DataRepresentationQosPolicy reference

inline DataRepresentationQosPolicy &representation()

Getter for DataRepresentationQosPolicy

Returns:

DataRepresentationQosPolicy reference

inline void representation(const DataRepresentationQosPolicy &representation)

Setter for DataRepresentationQosPolicy

Parameters:

representation – new value for the DataRepresentationQosPolicy

inline bool expects_inline_qos() const

Getter for expects_inline_qos

Returns:

expects_inline_qos

inline void expects_inline_qos(bool new_value)

Setter for expects_inline_qos

Parameters:

new_value – new value for the expects_inline_qos

inline PropertyPolicyQos &properties()

Getter for PropertyPolicyQos

Returns:

PropertyPolicyQos reference

inline const PropertyPolicyQos &properties() const

Getter for PropertyPolicyQos

Returns:

PropertyPolicyQos const reference

inline void properties(const PropertyPolicyQos &new_value)

Setter for PropertyPolicyQos

Parameters:

new_value – new value for the PropertyPolicyQos

inline RTPSEndpointQos &endpoint()

Getter for RTPSEndpointQos

Returns:

RTPSEndpointQos reference

inline const RTPSEndpointQos &endpoint() const

Getter for RTPSEndpointQos

Returns:

RTPSEndpointQos const reference

inline void endpoint(const RTPSEndpointQos &new_value)

Setter for RTPSEndpointQos

Parameters:

new_value – new value for the RTPSEndpointQos

inline ReaderResourceLimitsQos &reader_resource_limits()

Getter for ReaderResourceLimitsQos

Returns:

ReaderResourceLimitsQos reference

inline const ReaderResourceLimitsQos &reader_resource_limits() const

Getter for ReaderResourceLimitsQos

Returns:

ReaderResourceLimitsQos const reference

inline void reader_resource_limits(const ReaderResourceLimitsQos &new_value)

Setter for ReaderResourceLimitsQos

Parameters:

new_value – new value for the ReaderResourceLimitsQos

inline DataSharingQosPolicy &data_sharing()

Getter for DataSharingQosPolicy

Returns:

DataSharingQosPolicy reference

inline const DataSharingQosPolicy &data_sharing() const

Getter for DataSharingQosPolicy

Returns:

DataSharingQosPolicy reference

inline void data_sharing(const DataSharingQosPolicy &data_sharing)

Setter for DataSharingQosPolicy

Parameters:

data_sharing – new value for the DataSharingQosPolicy

const DataReaderQos eprosima::fastdds::dds::DATAREADER_QOS_DEFAULT
const DataReaderQos eprosima::fastdds::dds::DATAREADER_QOS_USE_TOPIC_QOS
20.1.4.4. InstanceStateKind
enum eprosima::fastdds::dds::InstanceStateKind

Indicates if the samples are from an alive eprosima::fastdds::dds::DataWriter or not.

For each instance, the middleware internally maintains an instance state. The instance state can be:

  • ALIVE_INSTANCE_STATE indicates that (a) samples have been received for the instance, (b) there are alive DataWriter entities writing the instance, and (c) the instance has not been explicitly disposed (or else more samples have been received after it was disposed).

The precise behavior events that cause the instance state to change depends on the setting of the OWNERSHIP QoS:

The instance state available in the SampleInfo is a snapshot of the instance state of the instance at the time the collection was obtained (i.e. at the time read or take was called). The instance state is therefore the same for all samples in the returned collection that refer to the same instance.

Values:

enumerator ALIVE_INSTANCE_STATE

Instance is currently in existence.

enumerator NOT_ALIVE_DISPOSED_INSTANCE_STATE

Not alive disposed instance. The instance has been disposed by a DataWriter.

enumerator NOT_ALIVE_NO_WRITERS_INSTANCE_STATE

Not alive no writers for instance. None of the DataWriter objects that are currently alive (according to the LIVELINESS QoS) are writing the instance.

20.1.4.5. ReadCondition
class ReadCondition : public eprosima::fastdds::dds::Condition

A Condition specifically dedicated to read operations and attached to one DataReader.

ReadCondition objects allow an application to specify the data samples it is interested in (by specifying the desired sample_states, view_states, and instance_states). The condition will only be triggered when suitable information is available. They are to be used in conjunction with a WaitSet as normal conditions. More than one ReadCondition may be attached to the same DataReader.

Public Functions

virtual bool get_trigger_value() const noexcept override

Retrieves the trigger_value of the Condition.

Returns:

true if trigger_value is set to ‘true’, ‘false’ otherwise

DataReader *get_datareader() const noexcept

Retrieves the DataReader associated with the ReadCondition.

Note that there is exactly one DataReader associated with each ReadCondition.

Returns:

pointer to the DataReader associated with this ReadCondition.

SampleStateMask get_sample_state_mask() const noexcept

Retrieves the set of sample_states taken into account to determine the trigger_value of this condition.

Returns:

the sample_states specified when the ReadCondition was created.

ViewStateMask get_view_state_mask() const noexcept

Retrieves the set of view_states taken into account to determine the trigger_value of this condition.

Returns:

the view_states specified when the ReadCondition was created.

InstanceStateMask get_instance_state_mask() const noexcept

Retrieves the set of instance_states taken into account to determine the trigger_value of this condition.

Returns:

the instance_states specified when the ReadCondition was created.

20.1.4.6. ReaderResourceLimitsQos
class ReaderResourceLimitsQos

Qos Policy to configure the limit of the reader resources.

Public Functions

ReaderResourceLimitsQos() = default

Constructor.

virtual ~ReaderResourceLimitsQos() = default

Destructor.

Public Members

fastdds::ResourceLimitedContainerConfig matched_publisher_allocation

Matched publishers allocation limits.

fastdds::ResourceLimitedContainerConfig sample_infos_allocation = {32u}

SampleInfo allocation limits.

fastdds::ResourceLimitedContainerConfig outstanding_reads_allocation = {2u}

Loaned collections allocation limits.

int32_t max_samples_per_read = 32

Maximum number of samples to return on a single call to read / take.

This attribute is a signed integer to be consistent with the max_samples argument of DataReader methods, but should always have a strict positive value. Bear in mind that a big number here may cause the creation of the DataReader to fail due to pre-allocation of internal resources.

Default value: 32.

20.1.4.7. RTPSReliableReaderQos
class RTPSReliableReaderQos

Qos Policy to configure the DisablePositiveACKsQos and the reader attributes.

Public Functions

inline RTPSReliableReaderQos()

Constructor.

virtual ~RTPSReliableReaderQos() = default

Destructor.

Public Members

fastdds::rtps::ReaderTimes times

Times associated with the Reliable Readers events.

DisablePositiveACKsQosPolicy disable_positive_acks

Control the sending of positive ACKs.

20.1.4.8. SampleInfo
struct SampleInfo

SampleInfo is the information that accompanies each sample that is ‘read’ or ‘taken.

Public Members

SampleStateKind sample_state

indicates whether or not the corresponding data sample has already been read

ViewStateKind view_state

indicates whether the DataReader has already seen samples for the most-current generation of the related instance.

InstanceStateKind instance_state

indicates whether the instance is currently in existence or, if it has been disposed, the reason why it was disposed.

int32_t disposed_generation_count

number of times the instance had become alive after it was disposed

int32_t no_writers_generation_count

number of times the instance had become alive after it was disposed because no writers

int32_t sample_rank

number of samples related to the same instance that follow in the collection

int32_t generation_rank

the generation difference between the time the sample was received, and the time the most recent sample in the collection was received.

int32_t absolute_generation_rank

the generation difference between the time the sample was received, and the time the most recent sample was received. The most recent sample used for the calculation may or may not be in the returned collection

rtps::Time_t source_timestamp

time provided by the DataWriter when the sample was written

rtps::Time_t reception_timestamp

time provided by the DataReader when the sample was added to its history

InstanceHandle_t instance_handle

identifies locally the corresponding instance

InstanceHandle_t publication_handle

identifies locally the DataWriter that modified the instance

Is the same InstanceHandle_t that is returned by the operation get_matched_publications on the DataReader

bool valid_data

whether the DataSample contains data or is only used to communicate of a change in the instance

rtps::SampleIdentity sample_identity

Sample Identity (Extension for RPC)

rtps::SampleIdentity related_sample_identity

Related Sample Identity (Extension for RPC)

20.1.4.9. SampleStateKind
enum eprosima::fastdds::dds::SampleStateKind

Indicates whether or not a sample has ever been read.

For each sample received, the middleware internally maintains a sample state relative to each DataReader. This sample state can have the following values:

The sample state will, in general, be different for each sample in the collection returned by read or take.

Values:

enumerator READ_SAMPLE_STATE

Sample has been read.

enumerator NOT_READ_SAMPLE_STATE

Sample has not been read.

20.1.4.10. Subscriber
class Subscriber : public eprosima::fastdds::dds::DomainEntity

Class Subscriber, contains the public API that allows the user to control the reception of messages. This class should not be instantiated directly. DomainRTPSParticipant class should be used to correctly create this element.

Public Functions

inline virtual ~Subscriber()

Destructor.

virtual ReturnCode_t enable() override

This operation enables the Subscriber.

Returns:

RETCODE_OK is successfully enabled. RETCODE_PRECONDITION_NOT_MET if the participant creating this Subscriber is not enabled.

const SubscriberQos &get_qos() const

Allows accessing the Subscriber Qos.

Returns:

SubscriberQos reference

ReturnCode_t get_qos(SubscriberQos &qos) const

Retrieves the Subscriber Qos.

Parameters:

qosSubscriberQos where the qos is returned

Returns:

RETCODE_OK

ReturnCode_t set_qos(const SubscriberQos &qos)

Allows modifying the Subscriber Qos. The given Qos must be supported by the SubscriberQos.

Parameters:

qos – new value for SubscriberQos

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const SubscriberListener *get_listener() const

Retrieves the attached SubscriberListener.

Returns:

Pointer to the SubscriberListener

ReturnCode_t set_listener(SubscriberListener *listener)

Modifies the SubscriberListener, sets the mask to StatusMask::all()

Parameters:

listener – new value for SubscriberListener

Returns:

RETCODE_OK

ReturnCode_t set_listener(SubscriberListener *listener, const StatusMask &mask)

Modifies the SubscriberListener.

Parameters:
Returns:

RETCODE_OK

DataReader *create_datareader(TopicDescription *topic, const DataReaderQos &reader_qos, DataReaderListener *listener = nullptr, const StatusMask &mask = StatusMask::all(), std::shared_ptr<fastdds::rtps::IPayloadPool> payload_pool = nullptr)

This operation creates a DataReader. The returned DataReader will be attached and belong to the Subscriber.

Parameters:
  • topicTopic the DataReader will be listening.

  • reader_qos – QoS of the DataReader.

  • listener – Pointer to the listener (default: nullptr)

  • maskStatusMask that holds statuses the listener responds to (default: all).

  • payload_pool – IPayloadPool shared pointer that defines reader payload (default: nullptr).

Returns:

Pointer to the created DataReader. nullptr if failed.

DataReader *create_datareader_with_profile(TopicDescription *topic, const std::string &profile_name, DataReaderListener *listener = nullptr, const StatusMask &mask = StatusMask::all(), std::shared_ptr<fastdds::rtps::IPayloadPool> payload_pool = nullptr)

This operation creates a DataReader. The returned DataReader will be attached and belongs to the Subscriber.

Parameters:
  • topicTopic the DataReader will be listening.

  • profile_nameDataReader profile name.

  • listener – Pointer to the listener (default: nullptr)

  • maskStatusMask that holds statuses the listener responds to (default: all).

  • payload_pool – IPayloadPool shared pointer that defines reader payload (default: nullptr).

Returns:

Pointer to the created DataReader. nullptr if failed.

ReturnCode_t delete_datareader(const DataReader *reader)

This operation deletes a DataReader that belongs to the Subscriber.

The delete_datareader operation must be called on the same Subscriber object used to create the DataReader. If delete_datareader is called on a different Subscriber, the operation will have no effect and it will return an error.

Parameters:

readerDataReader to delete

Returns:

RETCODE_PRECONDITION_NOT_MET if the datareader does not belong to this subscriber, RETCODE_OK if it is correctly deleted and RETCODE_ERROR otherwise.

DataReader *lookup_datareader(const std::string &topic_name) const

This operation retrieves a previously-created DataReader belonging to the Subscriber that is attached to a Topic with a matching topic_name. If no such DataReader exists, the operation will return nullptr.

If multiple DataReaders attached to the Subscriber satisfy this condition, then the operation will return one of them. It is not specified which one.

Parameters:

topic_name – Name of the topic associated to the DataReader

Returns:

Pointer to a previously created DataReader created on a Topic with that topic_name

ReturnCode_t get_datareaders(std::vector<DataReader*> &readers) const

This operation allows the application to access the DataReader objects.

Parameters:

readers – Vector of DataReader where the list of existing readers is returned

Returns:

RETCODE_OK

ReturnCode_t get_datareaders(std::vector<DataReader*> &readers, const std::vector<SampleStateKind> &sample_states, const std::vector<ViewStateKind> &view_states, const std::vector<InstanceStateKind> &instance_states) const

This operation allows the application to access the DataReader objects that contain samples with the specified sample_states, view_states, and instance_states.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:
  • readers[out] Vector of DataReader where the list of existing readers is returned

  • sample_states – Vector of SampleStateKind

  • view_states – Vector of ViewStateKind

  • instance_states – Vector of InstanceStateKind

Returns:

RETCODE_OK

bool has_datareaders() const

This operation checks if the subscriber has DataReaders

Returns:

true if the subscriber has one or several DataReaders, false in other case

ReturnCode_t begin_access()

Indicates that the application is about to access the data samples in any of the DataReader objects attached to the Subscriber.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Returns:

RETCODE_OK

ReturnCode_t end_access()

Indicates that the application has finished accessing the data samples in DataReader objects managed by the Subscriber.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Returns:

RETCODE_OK

ReturnCode_t notify_datareaders() const

This operation invokes the operation on_data_available on the DataReaderListener objects attached to contained DataReader entities.

This operation is typically invoked from the on_data_on_readers operation in the SubscriberListener. That way the SubscriberListener can delegate to the DataReaderListener objects the handling of the data.

Returns:

RETCODE_OK

ReturnCode_t delete_contained_entities()

Deletes all contained DataReaders. If the DataReaders have any QueryCondition or ReadCondition, they are deleted before the DataReader itself.

Returns:

RETCODE_OK if successful, an error code otherwise

ReturnCode_t set_default_datareader_qos(const DataReaderQos &qos)

This operation sets a default value of the DataReader QoS policies which will be used for newly created DataReader entities in the case where the QoS policies are defaulted in the create_datareader operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return false.

The special value DATAREADER_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_datareader_qos operation had never been called.

Parameters:

qos – new value for DataReaderQos to set as default

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

const DataReaderQos &get_default_datareader_qos() const

This operation returns the default value of the DataReader QoS, that is, the QoS policies which will be used for newly created DataReader entities in the case where the QoS policies are defaulted in the create_datareader operation.

The values retrieved get_default_datareader_qos will match the set of values specified on the last successful call to get_default_datareader_qos, or else, if the call was never made, the default values.

Returns:

Current default DataReaderQos.

DataReaderQos &get_default_datareader_qos()

This operation returns the default value of the DataReader QoS, that is, the QoS policies which will be used for newly created DataReader entities in the case where the QoS policies are defaulted in the create_datareader operation.

The values retrieved get_default_datareader_qos will match the set of values specified on the last successful call to get_default_datareader_qos, or else, if the call was never made, the default values.

Returns:

Current default DataReaderQos.

ReturnCode_t get_default_datareader_qos(DataReaderQos &qos) const

This operation retrieves the default value of the DataReader QoS, that is, the QoS policies which will be used for newly created DataReader entities in the case where the QoS policies are defaulted in the create_datareader operation.

The values retrieved get_default_datareader_qos will match the set of values specified on the last successful call to get_default_datareader_qos, or else, if the call was never made, the default values.

Parameters:

qosDataReaderQos where the default_qos is returned

Returns:

RETCODE_OK

ReturnCode_t get_datareader_qos_from_profile(const std::string &profile_name, DataReaderQos &qos) const

Fills the DataReaderQos with the values of the XML profile.

Parameters:
Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datareader_qos_from_profile(const std::string &profile_name, DataReaderQos &qos, std::string &topic_name) const

Fills the DataReaderQos with the values of the XML profile, and also its corresponding topic name (if specified).

Parameters:
  • profile_nameDataReader profile name.

  • qosDataReaderQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datareader_qos_from_xml(const std::string &xml, DataReaderQos &qos) const

Fills the DataReaderQos with the first DataReader profile found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataReaderQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datareader_qos_from_xml(const std::string &xml, DataReaderQos &qos, std::string &topic_name) const

Fills the DataReaderQos with the first DataReader profile found in the provided XML, and also its corresponding topic name (if specified).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataReaderQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datareader_qos_from_xml(const std::string &xml, DataReaderQos &qos, const std::string &profile_name) const

Fills the DataReaderQos with the DataReader profile with profile_name to be found in the provided XML.

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataReaderQos object where the qos is returned.

  • profile_nameDataReader profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_datareader_qos_from_xml(const std::string &xml, DataReaderQos &qos, std::string &topic_name, const std::string &profile_name) const

Fills the DataReaderQos with the DataReader profile with profile_name to be found in the provided XML, and also its corresponding topic name (if specified).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataReaderQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

  • profile_nameDataReader profile name.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_datareader_qos_from_xml(const std::string &xml, DataReaderQos &qos) const

Fills the DataReaderQos with the default DataReader profile found in the provided XML (if there is).

Note

This method does not update the default datareader qos (returned by get_default_datareader_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataReaderQos object where the qos is returned.

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

ReturnCode_t get_default_datareader_qos_from_xml(const std::string &xml, DataReaderQos &qos, std::string &topic_name) const

Fills the DataReaderQos with the default DataReader profile found in the provided XML (if there is), and also its corresponding topic name (if specified).

Note

This method does not update the default datareader qos (returned by get_default_datareader_qos).

Parameters:
  • xml – Raw XML string containing the profile to be used to fill the qos structure.

  • qosDataReaderQos object where the qos is returned.

  • topic_name – String where the name of the topic associated to this profile is returned (if specified).

Returns:

RETCODE_OK on success. RETCODE_BAD_PARAMETER otherwise.

const DomainParticipant *get_participant() const

This operation returns the DomainParticipant to which the Subscriber belongs.

Returns:

DomainParticipant Pointer

const InstanceHandle_t &get_instance_handle() const

Returns the Subscriber’s handle.

Returns:

InstanceHandle of this Subscriber.

Public Static Functions

static ReturnCode_t copy_from_topic_qos(DataReaderQos &reader_qos, const TopicQos &topic_qos)

Copies TopicQos into the corresponding DataReaderQos.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:
  • reader_qos[inout]

  • topic_qos[in]

Returns:

RETCODE_OK if successful, an error code otherwise

20.1.4.11. SubscriberListener
class SubscriberListener : public eprosima::fastdds::dds::DataReaderListener

Class SubscriberListener, it should be used by the end user to implement specific callbacks to certain actions. It also inherits all DataReaderListener callbacks.

Subclassed by eprosima::fastdds::dds::DomainParticipantListener

Public Functions

inline SubscriberListener()

Constructor.

inline virtual ~SubscriberListener()

Destructor.

inline virtual void on_data_on_readers(Subscriber *sub)

Virtual function to be implemented by the user containing the actions to be performed when a new Data Message is available on any reader.

Parameters:

subSubscriber

20.1.4.12. SubscriberQos
class SubscriberQos

Class SubscriberQos, contains all the possible Qos that can be set for a determined Subscriber. Although these values can be set and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

Public Functions

inline SubscriberQos()

Constructor.

inline virtual ~SubscriberQos()

Destructor.

inline const PresentationQosPolicy &presentation() const

Getter for PresentationQosPolicy

Returns:

PresentationQosPolicy reference

inline PresentationQosPolicy &presentation()

Getter for PresentationQosPolicy

Returns:

PresentationQosPolicy reference

inline void presentation(const PresentationQosPolicy &presentation)

Setter for PresentationQosPolicy

Parameters:

presentation – new value for the PresentationQosPolicy

inline const PartitionQosPolicy &partition() const

Getter for PartitionQosPolicy

Returns:

PartitionQosPolicy reference

inline PartitionQosPolicy &partition()

Getter for PartitionQosPolicy

Returns:

PartitionQosPolicy reference

inline void partition(const PartitionQosPolicy &partition)

Setter for PartitionQosPolicy

Parameters:

partition – new value for the PartitionQosPolicy

inline const GroupDataQosPolicy &group_data() const

Getter for GroupDataQosPolicy

Returns:

GroupDataQosPolicy reference

inline GroupDataQosPolicy &group_data()

Getter for GroupDataQosPolicy

Returns:

GroupDataQosPolicy reference

inline void group_data(const GroupDataQosPolicy &group_data)

Setter for GroupDataQosPolicy

Parameters:

group_data – new value for the GroupDataQosPolicy

inline const EntityFactoryQosPolicy &entity_factory() const

Getter for EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference

inline EntityFactoryQosPolicy &entity_factory()

Getter for EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference

inline void entity_factory(const EntityFactoryQosPolicy &entity_factory)

Setter for EntityFactoryQosPolicy

Parameters:

entity_factory – new value for the EntityFactoryQosPolicy

const SubscriberQos eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT
20.1.4.13. ViewStateKind
enum eprosima::fastdds::dds::ViewStateKind

Indicates whether or not an instance is new.

For each instance (identified by the key), the middleware internally maintains a view state relative to each DataReader. This view state can have the following values:

  • NOT_NEW_VIEW_STATE indicates that the DataReader has already accessed samples of the same instance and that the instance has not been reborn since.

The view_state available in the SampleInfo is a snapshot of the view state of the instance relative to the DataReader used to access the samples at the time the collection was obtained (i.e. at the time read or take was called). The view_state is therefore the same for all samples in the returned collection that refer to the same instance.

Once an instance has been detected as not having any “live” writers and all the samples associated with the instance are “taken” from the DDSDataReader, the middleware can reclaim all local resources regarding the instance. Future samples will be treated as “never seen.”

Values:

enumerator NEW_VIEW_STATE

New instance.This latest generation of the instance has not previously been accessed.

enumerator NOT_NEW_VIEW_STATE

Not a new instance. This latest generation of the instance has previously been accessed.

20.1.5. Topic

20.1.5.1. TopicDataType
class TopicDataType

Class TopicDataType used to provide the DomainRTPSParticipant with the methods to serialize, deserialize and get the key of a specific data type. The user should created a class that inherits from this one, where Serialize and deserialize methods MUST be implemented.

Subclassed by eprosima::fastdds::dds::DynamicPubSubType, eprosima::fastdds::dds::xtypes::AppliedAnnotationParameterPubSubType, eprosima::fastdds::dds::xtypes::AppliedAnnotationPubSubType, eprosima::fastdds::dds::xtypes::AppliedBuiltinMemberAnnotationsPubSubType, eprosima::fastdds::dds::xtypes::AppliedBuiltinTypeAnnotationsPubSubType, eprosima::fastdds::dds::xtypes::AppliedVerbatimAnnotationPubSubType, eprosima::fastdds::dds::xtypes::CommonAliasBodyPubSubType, eprosima::fastdds::dds::xtypes::CommonAnnotationParameterPubSubType, eprosima::fastdds::dds::xtypes::CommonArrayHeaderPubSubType, eprosima::fastdds::dds::xtypes::CommonBitfieldPubSubType, eprosima::fastdds::dds::xtypes::CommonBitflagPubSubType, eprosima::fastdds::dds::xtypes::CommonBitmaskHeaderPubSubType, eprosima::fastdds::dds::xtypes::CommonCollectionElementPubSubType, eprosima::fastdds::dds::xtypes::CommonCollectionHeaderPubSubType, eprosima::fastdds::dds::xtypes::CommonDiscriminatorMemberPubSubType, eprosima::fastdds::dds::xtypes::CommonEnumeratedHeaderPubSubType, eprosima::fastdds::dds::xtypes::CommonEnumeratedLiteralPubSubType, eprosima::fastdds::dds::xtypes::CommonStructMemberPubSubType, eprosima::fastdds::dds::xtypes::CommonUnionMemberPubSubType, eprosima::fastdds::dds::xtypes::CompleteAliasBodyPubSubType, eprosima::fastdds::dds::xtypes::CompleteAliasHeaderPubSubType, eprosima::fastdds::dds::xtypes::CompleteAliasTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteAnnotationHeaderPubSubType, eprosima::fastdds::dds::xtypes::CompleteAnnotationParameterPubSubType, eprosima::fastdds::dds::xtypes::CompleteAnnotationTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteArrayHeaderPubSubType, eprosima::fastdds::dds::xtypes::CompleteArrayTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteBitfieldPubSubType, eprosima::fastdds::dds::xtypes::CompleteBitflagPubSubType, eprosima::fastdds::dds::xtypes::CompleteBitmaskTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteBitsetHeaderPubSubType, eprosima::fastdds::dds::xtypes::CompleteBitsetTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteCollectionElementPubSubType, eprosima::fastdds::dds::xtypes::CompleteCollectionHeaderPubSubType, eprosima::fastdds::dds::xtypes::CompleteDiscriminatorMemberPubSubType, eprosima::fastdds::dds::xtypes::CompleteElementDetailPubSubType, eprosima::fastdds::dds::xtypes::CompleteEnumeratedHeaderPubSubType, eprosima::fastdds::dds::xtypes::CompleteEnumeratedLiteralPubSubType, eprosima::fastdds::dds::xtypes::CompleteEnumeratedTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteExtendedTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteMapTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteMemberDetailPubSubType, eprosima::fastdds::dds::xtypes::CompleteSequenceTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteStructHeaderPubSubType, eprosima::fastdds::dds::xtypes::CompleteStructMemberPubSubType, eprosima::fastdds::dds::xtypes::CompleteStructTypePubSubType, eprosima::fastdds::dds::xtypes::CompleteTypeDetailPubSubType, eprosima::fastdds::dds::xtypes::CompleteUnionHeaderPubSubType, eprosima::fastdds::dds::xtypes::CompleteUnionMemberPubSubType, eprosima::fastdds::dds::xtypes::CompleteUnionTypePubSubType, eprosima::fastdds::dds::xtypes::DummyPubSubType, eprosima::fastdds::dds::xtypes::ExtendedAnnotationParameterValuePubSubType, eprosima::fastdds::dds::xtypes::ExtendedTypeDefnPubSubType, eprosima::fastdds::dds::xtypes::MinimalAliasBodyPubSubType, eprosima::fastdds::dds::xtypes::MinimalAliasHeaderPubSubType, eprosima::fastdds::dds::xtypes::MinimalAliasTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalAnnotationHeaderPubSubType, eprosima::fastdds::dds::xtypes::MinimalAnnotationParameterPubSubType, eprosima::fastdds::dds::xtypes::MinimalAnnotationTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalArrayHeaderPubSubType, eprosima::fastdds::dds::xtypes::MinimalArrayTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalBitfieldPubSubType, eprosima::fastdds::dds::xtypes::MinimalBitflagPubSubType, eprosima::fastdds::dds::xtypes::MinimalBitmaskTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalBitsetHeaderPubSubType, eprosima::fastdds::dds::xtypes::MinimalBitsetTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalCollectionElementPubSubType, eprosima::fastdds::dds::xtypes::MinimalCollectionHeaderPubSubType, eprosima::fastdds::dds::xtypes::MinimalDiscriminatorMemberPubSubType, eprosima::fastdds::dds::xtypes::MinimalEnumeratedHeaderPubSubType, eprosima::fastdds::dds::xtypes::MinimalEnumeratedLiteralPubSubType, eprosima::fastdds::dds::xtypes::MinimalEnumeratedTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalExtendedTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalMapTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalMemberDetailPubSubType, eprosima::fastdds::dds::xtypes::MinimalSequenceTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalStructHeaderPubSubType, eprosima::fastdds::dds::xtypes::MinimalStructMemberPubSubType, eprosima::fastdds::dds::xtypes::MinimalStructTypePubSubType, eprosima::fastdds::dds::xtypes::MinimalTypeDetailPubSubType, eprosima::fastdds::dds::xtypes::MinimalUnionHeaderPubSubType, eprosima::fastdds::dds::xtypes::MinimalUnionMemberPubSubType, eprosima::fastdds::dds::xtypes::MinimalUnionTypePubSubType, eprosima::fastdds::dds::xtypes::PlainArrayLElemDefnPubSubType, eprosima::fastdds::dds::xtypes::PlainArraySElemDefnPubSubType, eprosima::fastdds::dds::xtypes::PlainCollectionHeaderPubSubType, eprosima::fastdds::dds::xtypes::PlainMapLTypeDefnPubSubType, eprosima::fastdds::dds::xtypes::PlainMapSTypeDefnPubSubType, eprosima::fastdds::dds::xtypes::PlainSequenceLElemDefnPubSubType, eprosima::fastdds::dds::xtypes::PlainSequenceSElemDefnPubSubType, eprosima::fastdds::dds::xtypes::StringLTypeDefnPubSubType, eprosima::fastdds::dds::xtypes::StringSTypeDefnPubSubType, eprosima::fastdds::dds::xtypes::StronglyConnectedComponentIdPubSubType, eprosima::fastdds::dds::xtypes::TypeIdentfierWithSizePubSubType, eprosima::fastdds::dds::xtypes::TypeIdentifierPairPubSubType, eprosima::fastdds::dds::xtypes::TypeIdentifierTypeObjectPairPubSubType, eprosima::fastdds::dds::xtypes::TypeIdentifierWithDependenciesPubSubType, eprosima::fastdds::dds::xtypes::TypeInformationPubSubType

Public Functions

TopicDataType() = default

Constructor.

virtual ~TopicDataType() = default

Destructor.

virtual bool serialize(const void *const data, rtps::SerializedPayload_t &payload, eprosima::fastdds::dds::DataRepresentationId_t data_representation) = 0

Serialize method, it should be implemented by the user, since it is abstract. If not implemented, this method will call the serialize method in which the topic data representation is not considered. It is VERY IMPORTANT that the user sets the SerializedPayload length correctly.

Parameters:
  • data[in] Pointer to the data

  • payload[out] Pointer to the payload

  • data_representation[in] Representation that should be used to encode the data into the payload.

Returns:

True if correct.

virtual bool deserialize(rtps::SerializedPayload_t &payload, void *data) = 0

Deserialize method, it should be implemented by the user, since it is abstract.

Parameters:
  • payload[in] Pointer to the payload

  • data[out] Pointer to the data

Returns:

True if correct.

virtual uint32_t calculate_serialized_size(const void *const data, eprosima::fastdds::dds::DataRepresentationId_t data_representation) = 0

Calculates the serialized size of the provided data.

Parameters:
  • data[in] Pointer to data.

  • data_representation[in] Representation that should be used for calculating the serialized size.

Returns:

Serialized size of the data.

virtual void *create_data() = 0

Create a Data Type.

Returns:

Void pointer to the created object.

virtual void delete_data(void *data) = 0

Remove a previously created object.

Parameters:

data – Pointer to the created Data.

virtual bool compute_key(rtps::SerializedPayload_t &payload, rtps::InstanceHandle_t &ihandle, bool force_md5 = false) = 0

Get the key associated with the data.

Parameters:
  • payload[in] Pointer to the payload containing the data.

  • ihandle[out] Pointer to the Handle.

  • force_md5[in] Force MD5 checking.

Returns:

True if correct.

virtual bool compute_key(const void *const data, rtps::InstanceHandle_t &ihandle, bool force_md5 = false) = 0

Get the key associated with the data.

Parameters:
  • data[in] Pointer to the data.

  • ihandle[out] Pointer to the Handle.

  • force_md5[in] Force MD5 checking.

Returns:

True if correct.

inline void set_name(const std::string &nam)

Set topic data type name

Parameters:

namTopic data type name

inline void set_name(std::string &&nam)

Set topic data type name

Parameters:

namTopic data type name

inline const std::string &get_name() const

Get topic data type name

Returns:

Topic data type name

inline const xtypes::TypeIdentifierPair &type_identifiers() const

Get the type identifiers

Returns:

xtypes::TypeIdentifierPair

inline virtual bool is_bounded() const

Checks if the type is bounded.

inline virtual bool is_plain(DataRepresentationId_t) const

Checks if the type is plain when using a specific encoding.

inline virtual bool construct_sample(void *memory) const

Construct a sample on a memory location.

Parameters:

memory – Pointer to the memory location where the sample should be constructed.

Returns:

whether this type supports in-place construction or not.

inline virtual void register_type_object_representation()

Register TypeObject type representation.

Public Members

uint32_t max_serialized_type_size = {0}

Maximum serialized size of the type in bytes. If the type has unbounded fields, and therefore cannot have a maximum size, use 0.

bool is_compute_key_provided = {false}

Indicates whether the method to obtain the key has been implemented.

20.1.5.2. TypeSupport
class TypeSupport : public std::shared_ptr<TopicDataType>

Class TypeSupport used to provide the DomainRTPSParticipant with the methods to serialize, deserialize and get the key of a specific data type. The user should created a class that inherits from this one, where Serialize and deserialize methods MUST be implemented.

Note

This class inherits from std::shared_ptr<TopicDataType>.

Public Functions

TypeSupport() noexcept = default

Constructor.

TypeSupport(const TypeSupport &type) noexcept = default

Copy Constructor.

Parameters:

type – Another instance of TypeSupport

TypeSupport(TypeSupport &&type) noexcept = default

Move Constructor.

Parameters:

type – Another instance of TypeSupport

TypeSupport &operator=(const TypeSupport &type) noexcept = default

Copy Assignment.

Parameters:

type – Another instance of TypeSupport

TypeSupport &operator=(TypeSupport &&type) noexcept = default

Move Assignment.

Parameters:

type – Another instance of TypeSupport

inline explicit TypeSupport(TopicDataType *ptr)

TypeSupport constructor that receives a TopicDataType pointer.

The passed pointer will be managed by the TypeSupport object, so creating two TypeSupport from the same pointer or deleting the passed pointer will produce a runtime error.

Parameters:

ptr

virtual ReturnCode_t register_type(DomainParticipant *participant) const

Registers the type on a participant.

Parameters:

participantDomainParticipant where the type is going to be registered

Returns:

RETCODE_BAD_PARAMETER if the type name is empty, RETCODE_PRECONDITION_NOT_MET if there is another type with the same name registered on the DomainParticipant and RETCODE_OK if it is registered correctly

virtual ReturnCode_t register_type(DomainParticipant *participant, std::string type_name) const

Registers the type on a participant.

Parameters:
  • participantDomainParticipant where the type is going to be registered

  • type_name – Name of the type to register

Returns:

RETCODE_BAD_PARAMETER if the type name is empty, RETCODE_PRECONDITION_NOT_MET if there is another type with the same name registered on the DomainParticipant and RETCODE_OK if it is registered correctly

inline virtual const std::string &get_type_name() const

Getter for the type name.

Returns:

name of the data type

virtual bool serialize(const void *const data, fastdds::rtps::SerializedPayload_t &payload, DataRepresentationId_t data_representation)

Serializes the data.

Parameters:
  • data – Pointer to data

  • payload – Pointer to payload

  • data_representation[in] Representation that should be used to encode the data into the payload.

Returns:

true if it is serialized correctly, false if not

virtual bool deserialize(fastdds::rtps::SerializedPayload_t &payload, void *data)

Deserializes the data.

Parameters:
  • payload – Pointer to payload

  • data – Pointer to data

Returns:

true if it is deserialized correctly, false if not

inline virtual uint32_t calculate_serialized_size(const void *const data, DataRepresentationId_t data_representation)

Returns a function which can be used to calculate the serialized size of the provided data.

Parameters:
  • data[in] Pointer to data.

  • data_representation[in] Representation that should be used for calculating the serialized size.

Returns:

Functor which calculates the serialized size of the data.

inline virtual void *create_data()

Creates new data.

Returns:

Pointer to the data

inline virtual void delete_data(void *data)

Deletes data.

Parameters:

data – Pointer to the data to delete

inline virtual bool compute_key(const void *const data, InstanceHandle_t &i_handle, bool force_md5 = false)

Getter for the data key.

Parameters:
  • data – Pointer to serialized payload containing the data.

  • i_handle – InstanceHandle pointer to store the key

  • force_md5 – boolean to force md5 (default: false)

Returns:

true if the key is returned, false if not

inline virtual bool compute_key(fastdds::rtps::SerializedPayload_t &payload, InstanceHandle_t &i_handle, bool force_md5 = false)

Getter for the data key.

Parameters:
  • payload – Pointer to data

  • i_handle – InstanceHandle pointer to store the key

  • force_md5 – boolean to force md5 (default: false)

Returns:

true if the key is returned, false if not

inline bool empty() const

Check if the TypeSupport is empty.

Returns:

true if empty, false if not

inline virtual bool is_bounded() const

Checks if the type is bounded.

inline virtual bool is_plain(DataRepresentationId_t data_representation) const

Checks if the type is plain when using a specific encoding.

20.1.5.3. TopicDescription
class TopicDescription

Class TopicDescription, represents the fact that both publications and subscriptions are tied to a single data-type

Subclassed by eprosima::fastdds::dds::ContentFilteredTopic, eprosima::fastdds::dds::Topic

Public Functions

virtual DomainParticipant *get_participant() const = 0

Get the DomainParticipant to which the TopicDescription belongs.

Returns:

The DomainParticipant to which the TopicDescription belongs.

inline const std::string &get_name() const

Get the name used to create this TopicDescription.

Returns:

the name used to create this TopicDescription.

inline const std::string &get_type_name() const

Get the associated type name.

Returns:

the type name.

20.1.5.4. Topic
class Topic : public eprosima::fastdds::dds::DomainEntity, public eprosima::fastdds::dds::TopicDescription

Class Topic, represents the fact that both publications and subscriptions are tied to a single data-type

Public Functions

virtual DomainParticipant *get_participant() const override

Getter for the DomainParticipant.

Returns:

DomainParticipant pointer

ReturnCode_t get_inconsistent_topic_status(InconsistentTopicStatus &status)

Allows the application to retrieve the INCONSISTENT_TOPIC_STATUS status of a Topic.

Warning

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Parameters:

status – [out] Status to be retrieved.

Returns:

RETCODE_OK

const TopicQos &get_qos() const

Allows accessing the Topic Qos.

Returns:

reference to TopicQos

ReturnCode_t get_qos(TopicQos &qos) const

Retrieves the Topic Qos.

Parameters:

qosTopicQos where the qos is returned

Returns:

RETCODE_OK

ReturnCode_t set_qos(const TopicQos &qos)

Allows modifying the Topic Qos. The given Qos must be supported by the Topic.

Parameters:

qos – new TopicQos value to set for the Topic.

Return values:
  • RETCODE_IMMUTABLE_POLICY – if a change was not allowed.

  • RETCODE_INCONSISTENT_POLICY – if new qos has inconsistent values.

  • RETCODE_OK – if qos was updated.

const TopicListener *get_listener() const

Retrieves the attached TopicListener.

Returns:

pointer to TopicListener

ReturnCode_t set_listener(TopicListener *listener, const StatusMask &mask = StatusMask::all())

Modifies the TopicListener.

Parameters:
  • listener – new value for the TopicListener

  • maskStatusMask that holds statuses the listener responds to (default: all).

Returns:

RETCODE_OK

20.1.5.5. ContentFilteredTopic
class ContentFilteredTopic : public eprosima::fastdds::dds::TopicDescription

Specialization of TopicDescription that allows for content-based subscriptions.

Public Functions

Getter for the related topic.

This operation returns the Topic associated with the ContentFilteredTopic. That is, the Topic specified when the ContentFilteredTopic was created.

const std::string &get_filter_expression() const

Get the filter expression.

This operation returns filter expression associated with this ContentFilteredTopic. It will return the filter_expression specified on the last successful call to set_expression or, if that method is never called, the expression specified when the ContentFilteredTopic was created.

Returns:

the filter_expression.

ReturnCode_t get_expression_parameters(std::vector<std::string> &expression_parameters) const

Get the expression parameters.

This operation returns expression parameters associated with this ContentFilteredTopic. These will be the expression_parameters specified on the last successful call to set_expression or set_expression_parameters. If those methods have never been called, the expression parameters specified when the ContentFilteredTopic was created will be returned.

Parameters:

expression_parameters[out] The expression parameters currently associated with the ContentFilteredTopic.

Returns:

RETCODE_OK

ReturnCode_t set_expression_parameters(const std::vector<std::string> &expression_parameters)

Set the expression parameters.

This operation changes expression parameters associated with this ContentFilteredTopic.

Parameters:

expression_parameters[in] The expression parameters to set.

Returns:

RETCODE_OK if the expression parameters where correctly updated.

Returns:

RETCODE_BAD_PARAMETER if the expression parameters do not match with the current filter_expression.

ReturnCode_t set_filter_expression(const std::string &filter_expression, const std::vector<std::string> &expression_parameters)

Set the filter expression and the expression parameters.

This operation changes the filter expression and the expression parameters associated with this ContentFilteredTopic.

Parameters:
  • filter_expression[in] The filter expression to set.

  • expression_parameters[in] The expression parameters to set.

Returns:

RETCODE_OK if the expression and parameters where correctly updated.

Returns:

RETCODE_BAD_PARAMETER if filter_expression is not valid for this ContentFilteredTopic.

Returns:

RETCODE_BAD_PARAMETER if the expression parameters do not match with the filter_expression.

virtual DomainParticipant *get_participant() const override

Getter for the DomainParticipant.

Returns:

DomainParticipant pointer

FASTDDS_SQLFILTER_NAME eprosima::fastdds::dds::sqlfilter_name
20.1.5.6. IContentFilter
struct IContentFilter

The interface that content filter objects should implement.

Public Functions

virtual bool evaluate(const SerializedPayload &payload, const FilterSampleInfo &sample_info, const GUID_t &reader_guid) const = 0

Evaluate if a serialized payload should be accepted by certain reader.

Parameters:
  • payload[in] The serialized payload of the sample being evaluated.

  • sample_info[in] The accompanying sample information.

  • reader_guid[in] The GUID of the reader for which the filter is being evaluated.

Returns:

whether the sample should be accepted for the specified reader.

struct FilterSampleInfo

Selected information from the cache change that is passed to the content filter object on payload evaluation.

Public Members

SampleIdentity sample_identity

Identity of the sample being filtered.

SampleIdentity related_sample_identity

Identity of a sample related to the one being filtered.

20.1.5.7. IContentFilterFactory
struct IContentFilterFactory

The interface that a factory of IContentFilter objects should implement.

Public Functions

virtual ReturnCode_t create_content_filter(const char *filter_class_name, const char *type_name, const TopicDataType *data_type, const char *filter_expression, const ParameterSeq &filter_parameters, IContentFilter *&filter_instance) = 0

Create or update an IContentFilter instance.

Parameters:
  • filter_class_name[in] Filter class name for which the factory is being called. Allows using the same factory for different filter classes.

  • type_name[in] Type name of the topic being filtered.

  • data_type[in] Type support object of the topic being filtered.

  • filter_expression[in] Content filter expression. May be nullptr when updating the parameters of a filter instance.

  • filter_parameters[in] Values to set for the filter parameters (n on the filter expression).

  • filter_instance[inout] When a filter is being created, it will be nullptr on input, and will have the pointer to the created filter instance on output. The caller takes ownership of the filter instance returned. When a filter is being updated, it will have a previously returned pointer on input. The method takes ownership of the filter instance during its execution, and can update the filter instance or even destroy it and create a new one. The caller takes ownership of the filter instance returned. It should always have a valid pointer upon return. The original state of the filter instance should be preserved when an error is returned.

Returns:

A return code indicating the result of the operation.

virtual ReturnCode_t delete_content_filter(const char *filter_class_name, IContentFilter *filter_instance) = 0

Delete an IContentFilter instance.

Parameters:
  • filter_class_name[in] Filter class name for which the factory is being called. Allows using the same factory for different filter classes.

  • filter_instance[in] A pointer to a filter instance previously returned by create_content_filter. The factory takes ownership of the filter instance, and can decide to destroy it or keep it for future use. In case of deletion, note this pointer must be downcasted to the derived class.

Returns:

A return code indicating the result of the operation.

20.1.5.8. TopicListener
class TopicListener

Class TopicListener, it should be used by the end user to implement specific callbacks to certain actions.

Subclassed by eprosima::fastdds::dds::DomainParticipantListener

Public Functions

inline TopicListener()

Constructor.

inline virtual ~TopicListener()

Destructor.

inline virtual void on_inconsistent_topic(Topic *topic, InconsistentTopicStatus status)

Virtual function to be implemented by the user containing the actions to be performed when another topic exists with the same name but different characteristics.

Parameters:
  • topicTopic

  • status – The inconsistent topic status

20.1.5.9. TopicQos
class TopicQos

Class TopicQos, containing all the possible Qos that can be set for a determined Topic. Although these values can be set and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

Public Functions

TopicQos()

Constructor.

inline const TopicDataQosPolicy &topic_data() const

Getter for TopicDataQosPolicy

Returns:

TopicDataQos reference

inline TopicDataQosPolicy &topic_data()

Getter for TopicDataQosPolicy

Returns:

TopicDataQos reference

inline void topic_data(const TopicDataQosPolicy &value)

Setter for TopicDataQosPolicy

Parameters:

value – new value for the TopicDataQosPolicy

inline const DurabilityQosPolicy &durability() const

Getter for DurabilityQosPolicy

Returns:

DurabilityQos reference

inline DurabilityQosPolicy &durability()

Getter for DurabilityQosPolicy

Returns:

DurabilityQos reference

inline void durability(const DurabilityQosPolicy &durability)

Setter for DurabilityQosPolicy

Parameters:

durability – new value for the DurabilityQosPolicy

inline const DurabilityServiceQosPolicy &durability_service() const

Getter for DurabilityServiceQosPolicy

Returns:

DurabilityServiceQos reference

inline DurabilityServiceQosPolicy &durability_service()

Getter for DurabilityServiceQosPolicy

Returns:

DurabilityServiceQos reference

inline void durability_service(const DurabilityServiceQosPolicy &durability_service)

Setter for DurabilityServiceQosPolicy

Parameters:

durability_service – new value for the DurabilityServiceQosPolicy

inline const DeadlineQosPolicy &deadline() const

Getter for DeadlineQosPolicy

Returns:

DeadlineQos reference

inline DeadlineQosPolicy &deadline()

Getter for DeadlineQosPolicy

Returns:

DeadlineQos reference

inline void deadline(const DeadlineQosPolicy &deadline)

Setter for DeadlineQosPolicy

Parameters:

deadline – new value for the DeadlineQosPolicy

inline const LatencyBudgetQosPolicy &latency_budget() const

Getter for LatencyBudgetQosPolicy

Returns:

LatencyBudgetQos reference

inline LatencyBudgetQosPolicy &latency_budget()

Getter for LatencyBudgetQosPolicy

Returns:

LatencyBudgetQos reference

inline void latency_budget(const LatencyBudgetQosPolicy &latency_budget)

Setter for LatencyBudgetQosPolicy

Parameters:

latency_budget – new value for the LatencyBudgetQosPolicy

inline const LivelinessQosPolicy &liveliness() const

Getter for LivelinessQosPolicy

Returns:

LivelinessQos reference

inline LivelinessQosPolicy &liveliness()

Getter for LivelinessQosPolicy

Returns:

LivelinessQos reference

inline void liveliness(const LivelinessQosPolicy &liveliness)

Setter for LivelinessQosPolicy

Parameters:

liveliness – new value for the LivelinessQosPolicy

inline const ReliabilityQosPolicy &reliability() const

Getter for ReliabilityQosPolicy

Returns:

ReliabilityQos reference

inline ReliabilityQosPolicy &reliability()

Getter for ReliabilityQosPolicy

Returns:

ReliabilityQos reference

inline void reliability(const ReliabilityQosPolicy &reliability)

Setter for ReliabilityQosPolicy

Parameters:

reliability – new value for the ReliabilityQosPolicy

inline const DestinationOrderQosPolicy &destination_order() const

Getter for DestinationOrderQosPolicy

Returns:

DestinationOrderQos reference

inline DestinationOrderQosPolicy &destination_order()

Getter for DestinationOrderQosPolicy

Returns:

DestinationOrderQos reference

inline void destination_order(const DestinationOrderQosPolicy &destination_order)

Setter for DestinationOrderQosPolicy

Parameters:

destination_order – new value for the DestinationOrderQosPolicy

inline const HistoryQosPolicy &history() const

Getter for HistoryQosPolicy

Returns:

HistoryQos reference

inline HistoryQosPolicy &history()

Getter for HistoryQosPolicy

Returns:

HistoryQos reference

inline void history(const HistoryQosPolicy &history)

Setter for HistoryQosPolicy

Parameters:

history – new value for the HistoryQosPolicy

inline const ResourceLimitsQosPolicy &resource_limits() const

Getter for ResourceLimitsQosPolicy

Returns:

ResourceLimitsQos reference

inline ResourceLimitsQosPolicy &resource_limits()

Getter for ResourceLimitsQosPolicy

Returns:

ResourceLimitsQos reference

inline void resource_limits(const ResourceLimitsQosPolicy &resource_limits)

Setter for ResourceLimitsQosPolicy

Parameters:

resource_limits – new value for the ResourceLimitsQosPolicy

inline const TransportPriorityQosPolicy &transport_priority() const

Getter for TransportPriorityQosPolicy

Returns:

TransportPriorityQos reference

inline TransportPriorityQosPolicy &transport_priority()

Getter for TransportPriorityQosPolicy

Returns:

TransportPriorityQos reference

inline void transport_priority(const TransportPriorityQosPolicy &transport_priority)

Setter for TransportPriorityQosPolicy

Parameters:

transport_priority – new value for the TransportPriorityQosPolicy

inline const LifespanQosPolicy &lifespan() const

Getter for LifespanQosPolicy

Returns:

LifespanQos reference

inline LifespanQosPolicy &lifespan()

Getter for LifespanQosPolicy

Returns:

LifespanQos reference

inline void lifespan(const LifespanQosPolicy &lifespan)

Setter for LifespanQosPolicy

Parameters:

lifespan – new value for the LifespanQosPolicy

inline const OwnershipQosPolicy &ownership() const

Getter for OwnershipQosPolicy

Returns:

OwnershipQos reference

inline OwnershipQosPolicy &ownership()

Getter for OwnershipQosPolicy

Returns:

OwnershipQos reference

inline void ownership(const OwnershipQosPolicy &ownership)

Setter for OwnershipQosPolicy

Parameters:

ownership – new value for the OwnershipQosPolicy

inline const DataRepresentationQosPolicy &representation() const

Getter for DataRepresentationQosPolicy

Returns:

DataRepresentationQosPolicy reference

inline DataRepresentationQosPolicy &representation()

Getter for DataRepresentationQosPolicy

Returns:

DataRepresentationQosPolicy reference

inline void representation(const DataRepresentationQosPolicy &representation)

Setter for DataRepresentationQosPolicy

Parameters:

representation – new value for the DataRepresentationQosPolicy

const TopicQos eprosima::fastdds::dds::TOPIC_QOS_DEFAULT
20.1.5.10. TypeInformationParameter
class TypeInformationParameter : public eprosima::fastdds::dds::Parameter_t, public eprosima::fastdds::dds::QosPolicy

Class xtypes::TypeInformationParameter

Public Functions

inline TypeInformationParameter()

Constructor.

inline TypeInformationParameter(const TypeInformationParameter &type)

Copy constructor.

Parameters:

type – Another instance of TypeInformationParameter

inline TypeInformationParameter(const eprosima::fastdds::dds::xtypes::TypeInformation &info)

Constructor using a TypeInformation.

Parameters:

info – TypeInformation to be set

inline TypeInformationParameter(TypeInformationParameter &&type)

Move Constructor.

Parameters:

type – Another instance of TypeInformationParameter

virtual ~TypeInformationParameter() override = default

Destructor.

inline virtual void clear() override

Clears the QosPolicy object.

inline bool assigned() const

Check if it is assigned.

Returns:

true if assigned, false if not

inline void assigned(bool value)

Setter for assigned boolean.

Parameters:

value – Boolean to be set

Public Members

eprosima::fastdds::dds::xtypes::TypeInformation type_information

Type Information.

20.1.6. XTypes

20.1.6.1. Dynamic Language Binding
20.1.6.1.1. AnnotationDescriptor
class AnnotationDescriptor

Public Functions

virtual traits<DynamicType>::ref_type type() const = 0

Returns a reference to the type.

The reference can be nil.

Returns:

DynamicType reference.

virtual traits<DynamicType>::ref_type &type() = 0

Returns a reference to the type.

The reference can be nil.

Returns:

DynamicType reference.

virtual void type(traits<DynamicType>::ref_type type) = 0

Modifies the underlying type reference.

Parameters:

type[in] DynamicType reference.

virtual ReturnCode_t get_value(ObjectName &value, const ObjectName &key) = 0

Getter given a key for the value property.

Parameters:
  • value[inout] The value.

  • key[in] Key used to retrieve the value.

Returns:

ReturnCode_t returns operation success

virtual ReturnCode_t get_all_value(Parameters &value) = 0

Getter for all the values.

Parameters:

value[inout] Parameters interface to the strings map.

Returns:

ReturnCode_t returns operation success.

virtual ReturnCode_t set_value(const ObjectName &key, const ObjectName &value) = 0

Setter given a key for the value property.

Parameters:
  • key[in] null terminated string

  • value[in] null terminated string

Returns:

ReturnCode_t returns operation success

virtual ReturnCode_t copy_from(traits<AnnotationDescriptor>::ref_type descriptor) = 0

Overwrites the contents of this descriptor with those of another descriptor (see [standard] 7.5.2.3.1)

Parameters:

descriptor[in] object

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil.

Returns:

standard ReturnCode_t

virtual bool equals(traits<AnnotationDescriptor>::ref_type descriptor) = 0

State comparison according with the [standard] sections 7.5.2.3.2

Parameters:

descriptor[in] reference.

Returns:

bool true on equality

virtual bool is_consistent() = 0

Indicates whether the states of all of this descriptor’s properties are consistent according with the [standard] section 7.5.2.3.3.

Returns:

bool true if consistent.

20.1.6.1.2. DynamicData
class DynamicData : public std::enable_shared_from_this<DynamicData>

Public Functions

virtual traits<DynamicType>::ref_type type() = 0

Retrieve the DynamicType reference associated to this DynamicData.

Returns:

Non-nil DynamicType reference

virtual ReturnCode_t get_descriptor(traits<MemberDescriptor>::ref_type &value, MemberId id) = 0

Retrieves the MemberDescriptor associated to a member.

Parameters:
  • value[inout] Non-nil MemberDescriptor reference where the information is copied.

  • id[in] Identifier of the member to be retrieved.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil or member identifier is not found.

virtual bool equals(traits<DynamicData>::ref_type other) = 0

Compares two DynamicData, equality requires:

  • Their respective type definitions are equal

  • All contained values are equal and occur in the same order

  • If the samples’ type is an aggregated type, previous rule shall be amended as follows:

    1. Members shall be compared without regard to their order.

Parameters:

other[in] DynamicData reference to compare to

Returns:

true on equality

virtual MemberId get_member_id_by_name(const ObjectName &name) = 0

Queries MemberId by name.

The query result depends on the type of the sample. Only next types support accessing by name.

  • Aggregated type.

  • Map type.

  • Bitmask type.

Parameters:

name[in] string

Returns:

MemberId or MEMBER_ID_INVALID on failure

virtual MemberId get_member_id_at_index(uint32_t index) = 0

Queries MemberId by index The query result depends on the type of the sample.

Only next types support accessing by index.

  • Aggregated type.

  • Sequence type.

  • String type.

  • Map type.

  • Array type.

  • Bitmask type.

Parameters:

index[in] Index.

Returns:

MemberId or MEMBER_ID_INVALID on failure

virtual uint32_t get_item_count() = 0

Provides the item count of the data and depends on the type of object:

  • If the object is of a collection type, returns the number of elements currently in the collection. In the case of an array type, this value will always be equal to the product of the bounds of all array dimensions.

  • If the object is of a bitmask type, return the number of named flags that are currently set in the bitmask.

  • If the object is of a structure or annotation type, return the number of members in the object. This value may be different than the number of members in the corresponding DynamicType.

  • If the object is of a union type, return the number of members in the object. This number will be two if the discriminator value selects a member and one otherwise.

  • if the object is of a primitive or enumerated type, it is atomic: return one.

  • if the object is of an alias type, return the value appropriate for the alias base type.

Returns:

count as defined above

virtual ReturnCode_t clear_all_values() = 0

Clear all members associated to the object.

Return values:

RETCODE_OK – when the cleaning was successful.

Returns:

ReturnCode_t

virtual ReturnCode_t clear_nonkey_values() = 0

Clear all members not associated to the key.

Return values:

RETCODE_OK – when the cleaning was successful.

Returns:

ReturnCode_t

virtual ReturnCode_t clear_value(MemberId id) = 0

Clear a member.

The meaning of “clearing” depends on the type of the sample:

  • If aggregated type, set it to its default value.

  • If variable-length collection type, remove the indicated element, shifting any subsequence elements to the next-lowest index.

  • If array type, set the indicated element to its default value.

  • If bitmask type, clear the indicated bit.

  • If enumerated type, set it to the first value of the enumerated type.

  • If primitive type, set it to its default value.

Parameters:

id[in] Identifier of the member to purge

Return values:
  • RETCODE_OK – when the cleaning was successful.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid.

Returns:

ReturnCode_t

virtual traits<DynamicData>::ref_type loan_value(MemberId id) = 0

Loans a DynamicData reference within the sample

Remark

This loan shall be returned by the DynamicData::return_loaned_value operation

Parameters:

id[in] identifier of the object to retrieve

Returns:

DynamicData reference loaned or nil on outstanding loaned data

virtual ReturnCode_t return_loaned_value(traits<DynamicData>::ref_type value) = 0

Returns a loan retrieved using DynamicData::loan_value.

Parameters:

value[in] DynamicData reference previously loaned

Return values:
  • RETCODE_OK – when the loan was returned successfully.

  • RETCODE_PRECONDITION_NOT_MET – when the loan is invalid.

virtual traits<DynamicData>::ref_type clone() = 0

Creates and returns a new data sample with the same contents as this one.

A comparison of this object and the clone using equals immediately following this call will return true.

Returns:

DynamicData reference

virtual ReturnCode_t get_int32_value(int32_t &value, MemberId id) = 0

Retrieves an int32 value associated to an identifier.

Parameters:
  • value[inout] int32 to populate

  • id[in] identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to int32.

Returns:

ReturnCode_t

virtual ReturnCode_t set_int32_value(MemberId id, int32_t value) = 0

Sets an int32 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] int32 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to int32.

Returns:

ReturnCode_t

virtual ReturnCode_t get_uint32_value(uint32_t &value, MemberId id) = 0

Retrieves an uint32 value associated to an identifier.

Parameters:
  • value[inout] uint32 to populate

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to uint32.

Returns:

ReturnCode_t

virtual ReturnCode_t set_uint32_value(MemberId id, uint32_t value) = 0

Sets an uint32 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] uint32 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to uint32.

Returns:

ReturnCode_t

virtual ReturnCode_t get_int8_value(int8_t &value, MemberId id) = 0

Retrieves an int8 value associated to an identifier.

Parameters:
  • value[inout] int8 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to int8.

Returns:

ReturnCode_t

virtual ReturnCode_t set_int8_value(MemberId id, int8_t value) = 0

Sets an int8 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] int8 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to int8.

Returns:

ReturnCode_t

virtual ReturnCode_t get_uint8_value(uint8_t &value, MemberId id) = 0

Retrieves an uint8 value associated to an identifier.

Parameters:
  • value[inout] uint8 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to uint8.

Returns:

ReturnCode_t

virtual ReturnCode_t set_uint8_value(MemberId id, uint8_t value) = 0

Sets an uint8 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] uint8 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to uint8.

Returns:

ReturnCode_t

virtual ReturnCode_t get_int16_value(int16_t &value, MemberId id) = 0

Retrieves an int16 value associated to an identifier.

Parameters:
  • value[inout] int16 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to int16.

Returns:

ReturnCode_t

virtual ReturnCode_t set_int16_value(MemberId id, int16_t value) = 0

Sets an int16 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] int16 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to int16.

Returns:

ReturnCode_t

virtual ReturnCode_t get_uint16_value(uint16_t &value, MemberId id) = 0

Retrieves an uint16 value associated to an identifier.

Parameters:
  • value[inout] uint16 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to uint16.

Returns:

ReturnCode_t

virtual ReturnCode_t set_uint16_value(MemberId id, uint16_t value) = 0

Sets an uint16 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] uint16 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to uint16.

Returns:

ReturnCode_t

virtual ReturnCode_t get_int64_value(int64_t &value, MemberId id) = 0

Retrieves an int64 value associated to an identifier.

Parameters:
  • value[inout] int64 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to int64.

Returns:

ReturnCode_t

virtual ReturnCode_t set_int64_value(MemberId id, int64_t value) = 0

Sets an int64 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] int64 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to int64.

Returns:

ReturnCode_t

virtual ReturnCode_t get_uint64_value(uint64_t &value, MemberId id) = 0

Retrieves an uint64 value associated to an identifier.

Parameters:
  • value[inout] uint64 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to uint64.

Returns:

ReturnCode_t

virtual ReturnCode_t set_uint64_value(MemberId id, uint64_t value) = 0

Sets an uint64 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] uint64 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to uint64.

Returns:

ReturnCode_t

virtual ReturnCode_t get_float32_value(float &value, MemberId id) = 0

Retrieves an float32 value associated to an identifier.

Parameters:
  • value[inout] float32 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to float32.

Returns:

ReturnCode_t

virtual ReturnCode_t set_float32_value(MemberId id, float value) = 0

Sets an float32 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] float32 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to float32.

Returns:

ReturnCode_t

virtual ReturnCode_t get_float64_value(double &value, MemberId id) = 0

Retrieves an float64 value associated to an identifier.

Parameters:
  • value[inout] float64 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to float64.

Returns:

ReturnCode_t

virtual ReturnCode_t set_float64_value(MemberId id, double value) = 0

Sets an float64 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] float64 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to float64.

Returns:

ReturnCode_t

virtual ReturnCode_t get_float128_value(long double &value, MemberId id) = 0

Retrieves an float128 value associated to an identifier.

Remark

Only available on platforms supporting long double

Parameters:
  • value[inout] float128 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to float128.

Returns:

ReturnCode_t

virtual ReturnCode_t set_float128_value(MemberId id, long double value) = 0

Sets an float128 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] float128 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to float128.

Returns:

ReturnCode_t

virtual ReturnCode_t get_char8_value(char &value, MemberId id) = 0

Retrieves an char8 value associated to an identifier.

Parameters:
  • value[inout] char8 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to char8.

Returns:

ReturnCode_t

virtual ReturnCode_t set_char8_value(MemberId id, char value) = 0

Sets an char8 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] char8 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to char8.

Returns:

ReturnCode_t

virtual ReturnCode_t get_char16_value(wchar_t &value, MemberId id) = 0

Retrieves an char16 value associated to an identifier.

Parameters:
  • value[inout] char16 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to char16.

Returns:

ReturnCode_t

virtual ReturnCode_t set_char16_value(MemberId id, wchar_t value) = 0

Sets an char16 value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] char16 to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to char16.

Returns:

ReturnCode_t

virtual ReturnCode_t get_byte_value(eprosima::fastdds::rtps::octet &value, MemberId id) = 0

Retrieves an byte value associated to an identifier.

Parameters:
  • value[inout] byte to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to byte.

Returns:

ReturnCode_t

virtual ReturnCode_t set_byte_value(MemberId id, eprosima::fastdds::rtps::octet value) = 0

Sets an byte value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] byte to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to byte.

Returns:

ReturnCode_t

virtual ReturnCode_t get_boolean_value(bool &value, MemberId id) = 0

Retrieves an bool value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to query.

  • value[inout] bool to populate.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to bool.

Returns:

ReturnCode_t

virtual ReturnCode_t set_boolean_value(MemberId id, bool value) = 0

Sets an bool value associated to an identifier.

Parameters:
  • id[in] identifier of the member to set.

  • value[in] bool to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to bool.

Returns:

ReturnCode_t

virtual ReturnCode_t get_string_value(std::string &value, MemberId id) = 0

Retrieves an string value associated to an identifier.

Parameters:
  • value[inout] string to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to string.

Returns:

ReturnCode_t

virtual ReturnCode_t set_string_value(MemberId id, const std::string &value) = 0

Sets an string value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] string to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to string or the string length is greater than the string bound.

Returns:

ReturnCode_t

virtual ReturnCode_t get_wstring_value(std::wstring &value, MemberId id) = 0

Retrieves an wstring value associated to an identifier.

Parameters:
  • value[inout] wstring to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to wstring.

Returns:

ReturnCode_t

virtual ReturnCode_t set_wstring_value(MemberId id, const std::wstring &value) = 0

Sets an wstring value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] wstring to set.

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to wstring or the string length is greater than the string bound.

Returns:

ReturnCode_t

virtual ReturnCode_t get_complex_value(traits<DynamicData>::ref_type &value, MemberId id) = 0

Retrieves a complex value associated to an identifier.

Parameters:
  • value[inout] DynamicData reference to populate

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to complex.

Returns:

ReturnCode_t

virtual ReturnCode_t set_complex_value(MemberId id, traits<DynamicData>::ref_type value) = 0

Sets a complex value associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] DynamicData reference to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the value reference is nil or MemberId is invalid or the member type is not promotable to complex.

Returns:

ReturnCode_t

virtual ReturnCode_t get_int32_values(Int32Seq &value, MemberId id) = 0

Retrieves a sequence of int32 values associated to an identifier.

Parameters:
  • value[inout] Sequence of int32 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of int32.

Returns:

ReturnCode_t

virtual ReturnCode_t set_int32_values(MemberId id, const Int32Seq &value) = 0

Sets a sequence of int32 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of int32 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of int32.

Returns:

ReturnCode_t

virtual ReturnCode_t get_uint32_values(UInt32Seq &value, MemberId id) = 0

Retrieves a sequence of uint32 values associated to an identifier.

Parameters:
  • value[inout] Sequence of uint32 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of uint32.

Returns:

ReturnCode_t

virtual ReturnCode_t set_uint32_values(MemberId id, const UInt32Seq &value) = 0

Sets a sequence of uint32 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of uint32 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of uint32.

Returns:

ReturnCode_t

virtual ReturnCode_t get_int8_values(Int8Seq &value, MemberId id) = 0

Retrieves a sequence of int8 values associated to an identifier.

Parameters:
  • value[inout] Sequence of int8 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of int8.

Returns:

ReturnCode_t

virtual ReturnCode_t set_int8_values(MemberId id, const Int8Seq &value) = 0

Sets a sequence of int8 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of int8 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of int8.

Returns:

ReturnCode_t

virtual ReturnCode_t get_uint8_values(UInt8Seq &value, MemberId id) = 0

Retrieves a sequence of uint8 values associated to an identifier.

Parameters:
  • value[inout] Sequence of uint8 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of uint8.

Returns:

ReturnCode_t

virtual ReturnCode_t set_uint8_values(MemberId id, const UInt8Seq &value) = 0

Sets a sequence of uint8 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of uint8 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of uint8.

Returns:

ReturnCode_t

virtual ReturnCode_t get_int16_values(Int16Seq &value, MemberId id) = 0

Retrieves a sequence of int16 values associated to an identifier.

Parameters:
  • value[inout] Sequence of int16 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of int16.

Returns:

ReturnCode_t

virtual ReturnCode_t set_int16_values(MemberId id, const Int16Seq &value) = 0

Sets a sequence of int16 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of int16 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of int16.

Returns:

ReturnCode_t

virtual ReturnCode_t get_uint16_values(UInt16Seq &value, MemberId id) = 0

Retrieves a sequence of uint16 values associated to an identifier.

Parameters:
  • value[inout] Sequence of uint16 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of uint16.

Returns:

ReturnCode_t

virtual ReturnCode_t set_uint16_values(MemberId id, const UInt16Seq &value) = 0

Sets a sequence of uint16 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of uint16 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of uint16.

Returns:

ReturnCode_t

virtual ReturnCode_t get_int64_values(Int64Seq &value, MemberId id) = 0

Retrieves a sequence of int64 values associated to an identifier.

Parameters:
  • value[inout] Sequence of int64 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of int64.

Returns:

ReturnCode_t

virtual ReturnCode_t set_int64_values(MemberId id, const Int64Seq &value) = 0

Sets a sequence of int64 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of int64 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of int64.

Returns:

ReturnCode_t

virtual ReturnCode_t get_uint64_values(UInt64Seq &value, MemberId id) = 0

Retrieves a sequence of uint64 values associated to an identifier.

Parameters:
  • value[inout] Sequence of uint64 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of uint64.

Returns:

ReturnCode_t

virtual ReturnCode_t set_uint64_values(MemberId id, const UInt64Seq &value) = 0

Sets a sequence of uint64 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of uint64 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of uint64.

Returns:

ReturnCode_t

virtual ReturnCode_t get_float32_values(Float32Seq &value, MemberId id) = 0

Retrieves a sequence of float32 values associated to an identifier.

Parameters:
  • value[inout] Sequence of float32 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of float32.

Returns:

ReturnCode_t

virtual ReturnCode_t set_float32_values(MemberId id, const Float32Seq &value) = 0

Sets a sequence of float32 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of float32 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of float32.

Returns:

ReturnCode_t

virtual ReturnCode_t get_float64_values(Float64Seq &value, MemberId id) = 0

Retrieves a sequence of float64 values associated to an identifier.

Parameters:
  • value[inout] Sequence of float64 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of float64.

Returns:

ReturnCode_t

virtual ReturnCode_t set_float64_values(MemberId id, const Float64Seq &value) = 0

Sets a sequence of float64 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of float64 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of float64.

Returns:

ReturnCode_t

virtual ReturnCode_t get_float128_values(Float128Seq &value, MemberId id) = 0

Retrieves a sequence of float128 values associated to an identifier.

Remark

Only available on platforms supporting long double

Parameters:
  • value[inout] Sequence of float128 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of float128.

Returns:

ReturnCode_t

virtual ReturnCode_t set_float128_values(MemberId id, const Float128Seq &value) = 0

Sets a sequence of float128 values associated to an identifier.

Remark

Only available on platforms supporting long double

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of float128 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of float128.

Returns:

ReturnCode_t

virtual ReturnCode_t get_char8_values(CharSeq &value, MemberId id) = 0

Retrieves a sequence of char8 values associated to an identifier.

Parameters:
  • value[inout] Sequence of char8 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of char8.

Returns:

ReturnCode_t

virtual ReturnCode_t set_char8_values(MemberId id, const CharSeq &value) = 0

Sets a sequence of char8 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of char8 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of char8.

Returns:

ReturnCode_t

virtual ReturnCode_t get_char16_values(WcharSeq &value, MemberId id) = 0

Retrieves a sequence of char16 values associated to an identifier.

Parameters:
  • value[inout] Sequence of char16 to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of char16.

Returns:

ReturnCode_t

virtual ReturnCode_t set_char16_values(MemberId id, const WcharSeq &value) = 0

Sets a sequence of char16 values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of char16 to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of char16.

Returns:

ReturnCode_t

virtual ReturnCode_t get_byte_values(ByteSeq &value, MemberId id) = 0

Retrieves a sequence of byte values associated to an identifier.

Parameters:
  • value[inout] Sequence of byte to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of byte.

Returns:

ReturnCode_t

virtual ReturnCode_t set_byte_values(MemberId id, const ByteSeq &value) = 0

Sets a sequence of byte values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of byte to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of byte.

Returns:

ReturnCode_t

virtual ReturnCode_t get_boolean_values(BooleanSeq &value, MemberId id) = 0

Retrieves a sequence of bool values associated to an identifier.

Parameters:
  • value[inout] Sequence of bool to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of bool.

Returns:

ReturnCode_t

virtual ReturnCode_t set_boolean_values(MemberId id, const BooleanSeq &value) = 0

Sets a sequence of bool values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of bool to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of bool.

Returns:

ReturnCode_t

virtual ReturnCode_t get_string_values(StringSeq &value, MemberId id) = 0

Retrieves a sequence of string values associated to an identifier.

Parameters:
  • value[inout] Sequence of string to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of string.

Returns:

ReturnCode_t

virtual ReturnCode_t set_string_values(MemberId id, const StringSeq &value) = 0

Sets a sequence of string values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of string to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of string.

Returns:

ReturnCode_t

virtual ReturnCode_t get_wstring_values(WstringSeq &value, MemberId id) = 0

Retrieves a sequence of wstring values associated to an identifier.

Parameters:
  • value[inout] Sequence of wstring to populate.

  • id[in] Identifier of the member to query.

Return values:
  • RETCODE_OK – when the value was retrieved successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of wstring.

Returns:

ReturnCode_t

virtual ReturnCode_t set_wstring_values(MemberId id, const WstringSeq &value) = 0

Sets a sequence of wstring values associated to an identifier.

Parameters:
  • id[in] Identifier of the member to set.

  • value[in] Sequence of wstring to set

Return values:
  • RETCODE_OK – when the value was set successfully.

  • RETCODE_BAD_PARAMETER – when the MemberId is invalid or the member type is not promotable to sequence of wstring.

Returns:

ReturnCode_t

20.1.6.1.3. DynamicDataFactory
class DynamicDataFactory : public std::enable_shared_from_this<DynamicDataFactory>

Public Functions

virtual traits<DynamicData>::ref_type create_data(traits<DynamicType>::ref_type type) = 0

Creates a new DynamicData reference based on the given DynamicType reference. All objects returned by this operation should eventually be deleted by calling delete_data.

Parameters:

type[in] DynamicType reference associated.

Returns:

new DynamicData reference

virtual ReturnCode_t delete_data(traits<DynamicData>::ref_type &data) = 0

Resets the internal reference if it is cached.

Parameters:

data[in] DynamicData reference whose internal cached reference to reset.

Return values:
  • RETCODE_BAD_PARAMETER – if reference is nil.

  • RETCODE_OK – is otherwise returned.

Returns:

standard ReturnCode_t

Public Static Functions

static traits<DynamicDataFactory>::ref_type get_instance()

Returns the singleton factory object.

Remark

This method is non thread-safe.

Returns:

DynamicDataFactory reference.

static ReturnCode_t delete_instance()

Resets the singleton reference.

Return values:
  • RETCODE_BAD_PARAMETER – if singleton reference is currently nil.

  • RETCODE_OK – otherwise.

Returns:

ReturnCode_t

20.1.6.1.4. DynamicPubSubType
class DynamicPubSubType : public virtual eprosima::fastdds::dds::TopicDataType

Public Functions

DynamicPubSubType(traits<DynamicType>::ref_type type)

Constructs a DynamicPubSubType from a DynamicType.

Remark

Ownership is not transferred.

Parameters:

typeDynamicType object associated to the data

DynamicPubSubType(traits<DynamicType>::ref_type type, const xtypes::TypeInformation &type_information)

Constructs a DynamicPubSubType from a DynamicType and a xtypes::TypeInformation.

This constructor is only meant to be used when the registration of the corresponding TypeSupport in the participant is meant to avoid registering the xtypes::TypeObject in the xtypes::TypeObjectRegistry; that is, when the xtypes::TypeObject registration has already been performed. This is for instance the case when the DynamicType is created from a xtypes::TypeObject obtained from a remote xtypes::TypeInformation that only has the minimal type identifiers but not the complete ones.

Remark

Ownership is not transferred.

Parameters:
  • typeDynamicType object associated to the data

  • type_information – xtypes::TypeInformation object associated to the data

virtual void *create_data() override

Create a new data object of the specified type.

Remark

Ownership is transferred. This object must be removed using delete_data

Returns:

pointer to the new object

virtual void delete_data(void *data) override

Deletes an object previously allocated via create_data.

Remark

Ownership is transferred. This object must be allocated using create_data

Parameters:

data – pointer to the object to be deleted

virtual bool deserialize(eprosima::fastdds::rtps::SerializedPayload_t &payload, void *data) override

Deserialize an object from the given payload.

Parameters:
Returns:

bool specifying success

traits<DynamicType>::ref_type get_dynamic_type() const noexcept

Returns a copy of the internal DynamicType object.

Returns:

pointer to the new object

virtual bool compute_key(eprosima::fastdds::rtps::SerializedPayload_t &payload, eprosima::fastdds::rtps::InstanceHandle_t &ihandle, bool force_md5 = false) override

Calculate the key associated to a given object.

Parameters:
Returns:

bool specifying success

virtual bool compute_key(const void *const data, eprosima::fastdds::rtps::InstanceHandle_t &ihandle, bool force_md5 = false) override

Calculate the key associated to a given object.

Parameters:
  • data – object which key is calculated

  • ihandlertps::InstanceHandle_t to fill in

  • force_md5 – use always md5 even if key payload footprint is smaller than the hash

Returns:

bool specifying success

virtual uint32_t calculate_serialized_size(const void *const data, DataRepresentationId_t data_representation) override

Provide a functor that calculates a specified object serialized size.

Parameters:
  • data[in] object whose payload footprint to calculate

  • data_representation[in] Representation that should be used for calculating the serialized size.

Returns:

functor that calculates the size

virtual bool serialize(const void *const data, eprosima::fastdds::rtps::SerializedPayload_t &payload, fastdds::dds::DataRepresentationId_t data_representation) override

Serialize an object into a given payload.

Parameters:
  • data[in] object to serialize

  • payload[out] rtps::SerializedPayload_t to fill in

  • data_representation[in] Representation that should be used to encode the data into the payload.

Returns:

bool specifying success

ReturnCode_t set_dynamic_type(traits<DynamicType>::ref_type type)

Sets up the internal DynamicType object.

Remark

Ownership is not transferred.

Parameters:

typeDynamicType to copy

Returns:

ReturnCode_t with operation status

virtual void register_type_object_representation() override

Register TypeObject representation in Fast DDS TypeObjectRegistry.

20.1.6.1.5. DynamicType
class DynamicType : public std::enable_shared_from_this<DynamicType>

Public Functions

virtual ReturnCode_t get_descriptor(traits<TypeDescriptor>::ref_type &descriptor) = 0

Provides a summary of the state of this type overwriting a provided object (see [standard] 7.5.2.8.7)

Parameters:

descriptor[inout] TypeDescriptor reference where copied the information.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil.

Returns:

ReturnCode_t

virtual ObjectName get_name() = 0

Returns the fully qualified name of this type.

Returns:

Type name.

virtual TypeKind get_kind() = 0

Returns the TypeKind associated.

Returns:

TypeKind

virtual ReturnCode_t get_member_by_name(traits<DynamicTypeMember>::ref_type &member, const ObjectName &name) = 0

Returns the member that corresponds to the specified name.

Parameters:
  • member[inout] DynamicTypeMember reference used to return the reference to the member.

  • name[in] Member name of the member being queried.

Return values:
  • RETCODE_OK – when the member was found.

  • RETCODE_BAD_PARAMETER – when the member doesn’t exist.

Returns:

ReturnCode_t

virtual ReturnCode_t get_all_members_by_name(DynamicTypeMembersByName &member) = 0

Returns all members by ObjectName.

Parameters:

member[inout] DynamicTypeMembersByName reference where the information is copied.

Return values:

RETCODE_OK

Returns:

ReturnCode_t

virtual ReturnCode_t get_member(traits<DynamicTypeMember>::ref_type &member, MemberId id) = 0

Returns the member that corresponds to the specified MemberId.

Parameters:
  • member[inout] DynamicTypeMember reference used to return the reference to the member.

  • id[in] MemberId

Return values:
  • RETCODE_OK – when the member was found.

  • RETCODE_BAD_PARAMETER – when the member doesn’t exist.

Returns:

ReturnCode_t

virtual ReturnCode_t get_all_members(DynamicTypeMembersById &member) = 0

Returns all members by MemberId.

Parameters:

member[inout] DynamicTypeMembersById reference where the information is copied.

Return values:

RETCODE_OK

Returns:

ReturnCode_t

virtual uint32_t get_member_count() = 0

This operation returns the current number of members.

Returns:

Current number of members

virtual ReturnCode_t get_member_by_index(traits<DynamicTypeMember>::ref_type &member, uint32_t index) = 0

This operation returns the member that corresponds to the specified index.

Parameters:
  • member[inout] DynamicTypeMember reference used to return the reference to the member.

  • index[in] Index

Return values:
  • RETCODE_OK – when the member was found.

  • RETCODE_BAD_PARAMETER – when the index is out-of-range.

Returns:

ReturnCode_t

virtual uint32_t get_annotation_count() = 0

Returns the number of applied annotations to the type.

Returns:

Number of annotations.

virtual ReturnCode_t get_annotation(traits<AnnotationDescriptor>::ref_type &descriptor, uint32_t idx) = 0

Returns an applied annotation by index.

Parameters:
  • descriptor[inout] AnnotationDescriptor reference where the information is copied.

  • idx[in] Index.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil or index is out-of-range.

Returns:

standard ReturnCode_t

virtual uint32_t get_verbatim_text_count() = 0

Returns the number of applied verbatim text to the type.

Returns:

Number of verbatim texts.

virtual ReturnCode_t get_verbatim_text(traits<VerbatimTextDescriptor>::ref_type &descriptor, uint32_t idx) = 0

Returns an applied verbatim text by index.

Parameters:
  • descriptor[inout] VerbatimTextDescriptor reference where the information is copied.

  • idx[in] Index.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil or index is out-of-range.

Returns:

standard ReturnCode_t

virtual bool equals(traits<DynamicType>::ref_type other) = 0

State comparison according with the [standard] sections 7.5.2.8.4

Parameters:

other[in] DynamicType reference to compare to

Returns:

bool true on equality

20.1.6.1.6. DynamicTypeBuilder
class DynamicTypeBuilder : public std::enable_shared_from_this<DynamicTypeBuilder>

Public Functions

virtual ReturnCode_t get_descriptor(traits<TypeDescriptor>::ref_type &descriptor) = 0

Provides a summary of the state of this type overwriting a provided object.

Parameters:

descriptor[inout] TypeDescriptor

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil.

Returns:

ReturnCode_t

virtual ObjectName get_name() = 0

Returns the fully qualified name of this type.

Returns:

Type name.

virtual TypeKind get_kind() = 0

Returns the TypeKind associated.

Returns:

TypeKind

virtual ReturnCode_t get_member_by_name(traits<DynamicTypeMember>::ref_type &member, const ObjectName &name) = 0

Returns a member looked for by name.

Parameters:
  • member[inout] DynamicTypeMember reference used to return the member.

  • name[in] Member name.

Return values:
  • RETCODE_OK – when member was found.

  • RETCODE_BAD_PARAMETER – when member wasn’t found.

Returns:

ReturnCode_t

virtual ReturnCode_t get_all_members_by_name(DynamicTypeMembersByName &member) = 0

Returns all members sorted by name.

Parameters:

member[inout] DynamicTypeMemberByName reference used to return all members.

Return values:

RETCODE_OK – always.

Returns:

ReturnCode_t

virtual ReturnCode_t get_member(traits<DynamicTypeMember>::ref_type &member, MemberId id) = 0

Returns a member looked for by MemberId.

Parameters:
  • member[inout] DynamicTypeMember reference used to return the member.

  • id[in] Member identifier.

Return values:
  • RETCODE_OK – when member was found.

  • RETCODE_BAD_PARAMETER – when member wasn’t found.

Returns:

ReturnCode_t

virtual ReturnCode_t get_all_members(DynamicTypeMembersById &member) = 0

Returns all members sorted by MemberId.

Parameters:

member[inout] DynamicTypeMemberById reference used to return all members.

Return values:

RETCODE_OK – always.

Returns:

ReturnCode_t

virtual uint32_t get_member_count() = 0

This operation returns the current number of members.

Returns:

Current number of members

virtual ReturnCode_t get_member_by_index(traits<DynamicTypeMember>::ref_type &member, uint32_t index) = 0

This operation returns the member that corresponds to the specified index.

Parameters:
  • member[inout] DynamicTypeMember reference used to return the member.

  • index[in] Index

Return values:
  • RETCODE_OK – when member was found.

  • RETCODE_BAD_PARAMETER – when index is out-of-range.

Returns:

ReturnCode_t

virtual uint32_t get_annotation_count() = 0

This operation returns the current number of annotations to the type.

Returns:

Current number of annotations

virtual ReturnCode_t get_annotation(traits<AnnotationDescriptor>::ref_type &descriptor, uint32_t idx) = 0

This operation returns the annotation that corresponds to the specified index.

Parameters:
  • descriptor[inout] AnnotationDescriptor reference where information is copied.

  • idx[in] Index

Return values:
  • RETCODE_OK – when member was found.

  • RETCODE_BAD_PARAMETER – when reference is nil or index is out-of-range.

Returns:

ReturnCode_t

virtual bool equals(traits<DynamicType>::ref_type other) = 0

Compares current state against a DynamicType reference.

Parameters:

other[in] DynamicType reference to compare to.

Returns:

bool true on equality

virtual ReturnCode_t add_member(traits<MemberDescriptor>::ref_type descriptor) = 0

Adds a ‘member’ to this type, where the new ‘member’ has the meaning defined in the specification of the DynamicTypeMember class.

Parameters:

descriptor[in] MemberDescriptor reference used for the new member.

Return values:
  • RETCODE_OK – when the member was created successfully.

  • RETCODE_BAD_PARAMETER – when there is an inconsistency.

  • RETCODE_PRECONDITION_NOT_MET – when the type does not have members.

Returns:

ReturnCode_t

virtual ReturnCode_t apply_annotation(traits<AnnotationDescriptor>::ref_type descriptor) = 0

Apply the given annotation to this type.

Parameters:

descriptor[in] AnnotationDescriptor reference to be applied.

Return values:
  • RETCODE_OK – when the annotation was applied successful.

  • RETCODE_BAD_PARAMETER – when there is an inconsistency.

Returns:

ReturnCode_t

virtual ReturnCode_t apply_annotation_to_member(MemberId member_id, traits<AnnotationDescriptor>::ref_type descriptor) = 0

Apply the given annotation to a member of this type.

Parameters:
  • member_id[in] Member identifier.

  • descriptor[in] AnnotationDescriptor reference to be applied.

Return values:
  • RETCODE_OK – when the annotation was applied successful.

  • RETCODE_BAD_PARAMETER – when there is an inconsistency.

Returns:

ReturnCode_t

virtual traits<DynamicType>::ref_type build() = 0

Create an immutable DynamicType object containing a snapshot of this builder’s current state.

Returns:

DynamicType reference.

20.1.6.1.7. DynamicTypeBuilderFactory
class DynamicTypeBuilderFactory : public std::enable_shared_from_this<DynamicTypeBuilderFactory>

Public Functions

virtual traits<DynamicType>::ref_type get_primitive_type(TypeKind kind) = 0

Retrieves the cached DynamicType reference associated to a given primitive.

Parameters:

kind[in] Type identifying the primitive type to retrieve.

Returns:

DynamicType reference. Nil reference returned in error case.

virtual traits<DynamicTypeBuilder>::ref_type create_type(traits<TypeDescriptor>::ref_type descriptor) = 0

Creates a new DynamicTypeBuilder reference based on the given TypeDescriptor state.

Parameters:

descriptor[in] TypeDescriptor to be copied.

Returns:

New DynamicTypeBuilder reference. Nil reference returned in error case.

virtual traits<DynamicTypeBuilder>::ref_type create_type_copy(traits<DynamicType>::ref_type type) = 0

Creates a new DynamicTypeBuilder reference based on the given DynamicType reference.

Parameters:

type[in] DynamicType reference to be used.

Returns:

New DynamicTypeBuilder reference. Nil reference returned in error case.

virtual traits<DynamicTypeBuilder>::ref_type create_type_w_type_object(const xtypes::TypeObject &type_object) = 0

Creates a new DynamicTypeBuilder reference based on the given xtypes::TypeObject instance.

Parameters:

type_object[in] xtypes::TypeObject instance to be used.

Returns:

New DynamicTypeBuilder reference. Nil reference returned in error case.

virtual traits<DynamicTypeBuilder>::ref_type create_string_type(uint32_t bound) = 0

Creates a new DynamicTypeBuilder reference representing a bounded string type.

Parameters:

bound[in] uint32_t representing the maximum number of elements that may be stored. If the value is equal to LENGTH_UNLIMITED, the string type shall be considered to be unbounded.

Returns:

new DynamicTypeBuilder reference.

virtual traits<DynamicTypeBuilder>::ref_type create_wstring_type(uint32_t bound) = 0

Creates a new DynamicTypeBuilder reference representing a bounded wstring type.

Parameters:

bound[in] uint32_t representing the maximum number of elements that may be stored. If the value is equal to LENGTH_UNLIMITED, the wstring type shall be considered to be unbounded.

Returns:

new DynamicTypeBuilder reference.

virtual traits<DynamicTypeBuilder>::ref_type create_sequence_type(traits<DynamicType>::ref_type element_type, uint32_t bound) = 0

Creates a new DynamicTypeBuilder reference representing a sequence.

Parameters:
  • element_type[in] DynamicType reference which becomes the element type

  • bound[in] uint32_t representing the maximum number of elements that may be stored. If the value is equal to LENGTH_UNLIMITED, the sequence type shall be considered to be unbounded.

Returns:

new DynamicTypeBuilder reference. Nil reference returned in error case.

virtual traits<DynamicTypeBuilder>::ref_type create_array_type(traits<DynamicType>::ref_type element_type, const BoundSeq &bound) = 0

Creates a new DynamicTypeBuilder reference representing an array.

Parameters:
  • element_type[in] DynamicType reference which becomes the element type

  • bound[in] uint32_t sequence representing the desired dimensions.

Returns:

new DynamicTypeBuilder reference. Nil reference returned in error case.

virtual traits<DynamicTypeBuilder>::ref_type create_map_type(traits<DynamicType>::ref_type key_element_type, traits<DynamicType>::ref_type element_type, uint32_t bound) = 0

Creates a new DynamicTypeBuilder reference representing a map.

Parameters:
  • key_element_type[in] DynamicType reference which becomes the map’s key type

  • element_type[in] DynamicType reference which becomes the map’s value type

  • bound[in] uint32_t representing the maximum number of elements that may be stored. If the value is equal to LENGTH_UNLIMITED, the map type shall be considered to be unbounded.

Returns:

new DynamicTypeBuilder reference. Nil reference returned in error case.

virtual traits<DynamicTypeBuilder>::ref_type create_bitmask_type(uint32_t bound) = 0

Creates a new DynamicTypeBuilder reference representing a bitmask.

Parameters:

bound[in] uint32_t representing the maximum number of elements that may be stored.

Returns:

new DynamicTypeBuilder reference. Nil reference returned in error case.

virtual void set_preprocessor(const std::string &preprocessor) = 0

Sets the path to the preprocessor executable to be used when parsing type descriptions.

Parameters:

preprocessor[in] path to the preprocessor executable.

virtual traits<DynamicTypeBuilder>::ref_type create_type_w_uri(const std::string &document_url, const std::string &type_name, const IncludePathSeq &include_paths) = 0

Creates a new DynamicTypeBuilder reference by parsing the type description at the given URL.

Parameters:
  • document_url[in] pointing to the url containing the type description.

  • type_name[in] Fully qualified name of the type to be loaded from the document.

  • include_paths[in] A collection of URLs to directories to be searched for additional type description documents.

Returns:

new DynamicTypeBuilder reference. Nil reference returned in error case.

virtual traits<DynamicTypeBuilder>::ref_type create_type_w_document(const std::string &document, const std::string &type_name, const IncludePathSeq &include_paths) = 0

Creates a new DynamicTypeBuilder reference by parsing the type description contained in the given string.

Remark

Not implemented yet.

Parameters:
  • document[in] containing the type description.

  • type_name[in] Fully qualified name of the type to be loaded from the string.

  • include_paths[in] A collection of URLs to directories to be searched for additional type description documents.

Returns:

new DynamicTypeBuilder reference. Nil reference returned in error case.

virtual ReturnCode_t delete_type(traits<DynamicType>::ref_type &type) = 0

Resets the internal reference if it is cached.

Parameters:

type[in] DynamicType reference whose internal cached reference to reset.

Return values:

RETCODE_OK – is always returned.

Returns:

standard ReturnCode_t

Public Static Functions

static traits<DynamicTypeBuilderFactory>::ref_type get_instance()

Returns the singleton factory object.

Remark

This method is non thread-safe.

Returns:

DynamicTypeBuilderFactory reference.

static ReturnCode_t delete_instance()

Resets the singleton reference.

Return values:
  • RETCODE_BAD_PARAMETER – if singleton reference is currently nil.

  • RETCODE_OK – otherwise.

Returns:

ReturnCode_t

20.1.6.1.8. DynamicTypeMember
class DynamicTypeMember : public std::enable_shared_from_this<DynamicTypeMember>

Represents a “member” of a type.

A “member” in this sense may be a member of an aggregated type, a constant within an enumeration, or some other type substructure.

Public Functions

virtual ReturnCode_t get_descriptor(traits<MemberDescriptor>::ref_type &descriptor) = 0

Provides a summary of the state of this type overwriting a provided object (see [standard] 7.5.2.6.2)

Parameters:

descriptor[inout] MemberDescriptor reference where the information is copied.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil.

Returns:

standard ReturnCode_t

virtual uint32_t get_annotation_count() = 0

Returns the number of applied annotations to the member.

Returns:

Number of annotations.

virtual ReturnCode_t get_annotation(traits<AnnotationDescriptor>::ref_type &descriptor, uint32_t idx) = 0

Returns an applied annotation by index.

Parameters:
  • descriptor[inout] AnnotationDescriptor reference where the information is copied.

  • idx[in] Index.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil or index is out-of-range.

Returns:

standard ReturnCode_t

virtual uint32_t get_verbatim_text_count() = 0

Returns the number of applied verbatim text to the member.

Returns:

Number of verbatim texts.

virtual ReturnCode_t get_verbatim_text(traits<VerbatimTextDescriptor>::ref_type &descriptor, uint32_t idx) = 0

Returns an applied verbatim text by index.

Parameters:
  • descriptor[inout] VerbatimTextDescriptor reference where the information is copied.

  • idx[in] Index.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil or index is out-of-range.

Returns:

standard ReturnCode_t

virtual bool equals(traits<DynamicTypeMember>::ref_type other) = 0

State comparison according with the [standard] sections 7.5.2.6.3

Parameters:

other[in] DynamicTypeMember reference to compare to

Returns:

bool true on equality

virtual MemberId get_id() = 0

Getter for id property according with the [standard] section 7.5.2.6.4

Returns:

MemberId

virtual ObjectName get_name() = 0

Returns the name of this member.

Returns:

Member name.

20.1.6.1.9. MemberDescriptor
class MemberDescriptor

Public Functions

virtual ObjectName &name() = 0

Returns the name of this member.

Returns:

Member’s name.

virtual const ObjectName &name() const = 0

Returns the name of this member.

Returns:

Member’s name.

virtual void name(const ObjectName &name) = 0

Modifies the underlying member’s name by copy.

Parameters:

name[in] Member’s name.

virtual void name(ObjectName &&name) = 0

Modifies the underlying member’s name by move.

Parameters:

name[in] Member’s name.

virtual MemberId id() const = 0

Returns the MemberId of the member.

Returns:

MemberId.

virtual MemberId &id() = 0

Returns the MemberId of the member.

Returns:

MemberId.

virtual void id(MemberId id) = 0

Modifies the underlying MemberId.

Parameters:

id[in] MemberId to be set.

virtual traits<DynamicType>::ref_type type() const = 0

Returns a reference to the member’s type.

Returns:

DynamicType reference.

virtual traits<DynamicType>::ref_type &type() = 0

Returns a reference to the member’s type.

Returns:

DynamicType reference.

virtual void type(traits<DynamicType>::ref_type type) = 0

Modifies the underlying member’s type reference.

Parameters:

type[in] DynamicType reference.

virtual std::string &default_value() = 0

Returns the default value.

Returns:

Default value.

virtual const std::string &default_value() const = 0

Returns the default value.

Returns:

Default value.

virtual void default_value(const std::string &default_value) = 0

Modifies the underlying default value by copy.

Parameters:

default_value[in] Default value.

virtual void default_value(std::string &&default_value) = 0

Modifies the underlying default value by move.

Parameters:

default_value[in] Default value.

virtual uint32_t &index() = 0

Returns the order of definition of the member.

Returns:

Order of definition.

virtual uint32_t index() const = 0

Returns the order of definition of the member.

Returns:

Order of definition.

virtual const UnionCaseLabelSeq &label() const = 0

Returns the labels the member belongs to.

Returns:

UnionCaseLabelSeq.

virtual UnionCaseLabelSeq &label() = 0

Returns the labels the member belongs to.

Returns:

UnionCaseLabelSeq.

virtual void label(const UnionCaseLabelSeq &label) = 0

Modifies the labels the member belongs to by copy.

Parameters:

label[in] UnionCaseLabelSeq

virtual void label(UnionCaseLabelSeq &&label) = 0

Modifies the labels the member belongs to by move.

Parameters:

label[in] UnionCaseLabelSeq

virtual TryConstructKind try_construct_kind() const = 0

Returns the TryConstructKind of the member.

Returns:

TryConstructKind.

virtual TryConstructKind &try_construct_kind() = 0

Returns the TryConstructKind of the member.

Returns:

TryConstructKind.

virtual void try_construct_kind(TryConstructKind try_construct_kind) = 0

Modifies the TryConstructKind of the member.

Parameters:

try_construct_kind[in] TryConstructKind.

virtual bool is_key() const = 0

Returns the if the member is key.

Returns:

If the member is key.

virtual bool &is_key() = 0

Returns the if the member is key.

Returns:

If the member is key.

virtual void is_key(bool is_key) = 0

Modifies if the member is key.

Parameters:

is_key[in] Boolean

virtual bool is_optional() const = 0

Returns the if the member is optional.

Returns:

If the member is optional.

virtual bool &is_optional() = 0

Returns the if the member is optional.

Returns:

If the member is optional.

virtual void is_optional(bool is_optional) = 0

Modifies if the member is optional.

Parameters:

is_optional[in] Boolean

virtual bool is_must_understand() const = 0

Returns the if the member is must_understand.

Returns:

If the member is must_understand.

virtual bool &is_must_understand() = 0

Returns the if the member is must_understand.

Returns:

If the member is must_understand.

virtual void is_must_understand(bool is_must_understand) = 0

Modifies if the member is must_understand.

Parameters:

is_must_understand[in] Boolean

virtual bool is_shared() const = 0

Returns the if the member is shared.

Returns:

If the member is shared.

virtual bool &is_shared() = 0

Returns the if the member is shared.

Returns:

If the member is shared.

virtual void is_shared(bool is_shared) = 0

Modifies if the member is shared.

Parameters:

is_shared[in] Boolean

virtual bool is_default_label() const = 0

Returns the if the member is default_label.

Returns:

If the member is default_label.

virtual bool &is_default_label() = 0

Returns the if the member is default_label.

Returns:

If the member is default_label.

virtual void is_default_label(bool is_default_label) = 0

Modifies if the member is default_label.

Parameters:

is_default_label[in] Boolean

virtual ReturnCode_t copy_from(traits<MemberDescriptor>::ref_type descriptor) = 0

Overwrites the contents of this descriptor with those of another descriptor (see [standard] 7.5.2.7.1).

Parameters:

descriptor[in] reference.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil.

Returns:

ReturnCode_t

virtual bool equals(traits<MemberDescriptor>::ref_type descriptor) = 0

Compares according with the [standard] section 7.5.2.7.4.

Parameters:

descriptor[in] reference to compare to.

Returns:

bool true on equality

virtual bool is_consistent() = 0

Indicates whether the states of all of this descriptor’s properties are consistent according with the [standard] section 7.5.2.7.7.

Returns:

bool true if consistent.

20.1.6.1.10. TypeDescriptor
class TypeDescriptor

TypeDescriptor definition according to [standard] section 7.5.2.4.

Public Functions

virtual TypeKind kind() const = 0

Returns the TypeKind associated.

Returns:

standard TypeKind.

virtual TypeKind &kind() = 0

Returns the TypeKind associated.

Returns:

standard TypeKind.

virtual void kind(TypeKind kind) = 0

Modifies the underlying TypeKind.

Parameters:

kind[in] TypeKind to be set.

virtual ObjectName &name() = 0

Returns the fully qualified name of this type.

Returns:

Fully qualified name.

virtual const ObjectName &name() const = 0

Returns the fully qualified name of this type.

Returns:

Fully qualified name.

virtual void name(const ObjectName &name) = 0

Modifies the underlying type name by copy.

Parameters:

name[in] Fully qualified name.

virtual void name(ObjectName &&name) = 0

Modifies the underlying type name by move.

Parameters:

name[in] Fully qualified name.

virtual traits<DynamicType>::ref_type base_type() const = 0

Returns a reference to the base type.

The reference can be nil.

Returns:

DynamicType reference.

virtual traits<DynamicType>::ref_type &base_type() = 0

Returns a reference to the base type.

The reference can be nil.

Returns:

DynamicType reference.

virtual void base_type(traits<DynamicType>::ref_type type) = 0

Modifies the underlying base type reference.

Parameters:

type[in] DynamicType reference.

virtual traits<DynamicType>::ref_type discriminator_type() const = 0

Returns a reference discriminator type.

The reference can be nil.

Returns:

DynamicType reference.

virtual traits<DynamicType>::ref_type &discriminator_type() = 0

Returns a reference discriminator type.

The reference can be nil.

Returns:

DynamicType reference.

virtual void discriminator_type(traits<DynamicType>::ref_type type) = 0

Modifies the underlying discriminator type reference.

Parameters:

type[in] DynamicType reference.

virtual const BoundSeq &bound() const = 0

Returns the bound.

Returns:

BoundSeq.

virtual BoundSeq &bound() = 0

Returns the bound.

Returns:

BoundSeq.

virtual void bound(const BoundSeq &bound) = 0

Modifies the underlying bound by copy.

Parameters:

bound[in] BoundSeq

virtual void bound(BoundSeq &&bound) = 0

Modifies the underlying bound by move.

Parameters:

bound[in] BoundSeq

virtual traits<DynamicType>::ref_type element_type() const = 0

Returns a reference element type.

The reference can be nil.

Returns:

DynamicType reference.

virtual traits<DynamicType>::ref_type &element_type() = 0

Returns a reference element type.

The reference can be nil.

Returns:

DynamicType reference.

virtual void element_type(traits<DynamicType>::ref_type type) = 0

Modifies the underlying element type reference.

Parameters:

type[in] DynamicType reference.

virtual traits<DynamicType>::ref_type key_element_type() const = 0

Returns a reference key element type.

The reference can be nil.

Returns:

DynamicType reference.

virtual traits<DynamicType>::ref_type &key_element_type() = 0

Returns a reference key element type.

The reference can be nil.

Returns:

DynamicType reference.

virtual void key_element_type(traits<DynamicType>::ref_type type) = 0

Modifies the underlying key element type reference.

Parameters:

type[in] DynamicType reference.

virtual ExtensibilityKind extensibility_kind() const = 0

Returns the extensibility kind.

return ExtensibilityKind

virtual ExtensibilityKind &extensibility_kind() = 0

Returns the extensibility kind.

return ExtensibilityKind

virtual void extensibility_kind(ExtensibilityKind extensibility_kind) = 0

Modifies the extensibility kind.

Parameters:

extensibility_kind[in] ExtensibilityKind

virtual bool is_nested() const = 0

Returns the is_nested property.

return Boolean

virtual bool &is_nested() = 0

Returns the is_nested property.

return Boolean

virtual void is_nested(bool is_nested) = 0

Modifies the is_nested property.

Parameters:

is_nested[in] Boolean value to be set.

virtual ReturnCode_t copy_from(traits<TypeDescriptor>::ref_type descriptor) = 0

Overwrites the contents of this descriptor with those of another descriptor (see [standard] 7.5.2.4.3).

Parameters:

descriptor[in] reference.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil.

Returns:

ReturnCode_t

virtual bool equals(traits<TypeDescriptor>::ref_type descriptor) = 0

Compares according with the [standard] section 7.5.2.4.6.

Parameters:

descriptor[in] reference to compare to.

Returns:

bool true on equality

virtual bool is_consistent() = 0

Indicates whether the states of all of this descriptor’s properties are consistent according with the [standard] section 7.5.2.4.7.

Returns:

bool true if consistent.

20.1.6.1.11. VerbatimTextDescriptor
class VerbatimTextDescriptor

Public Functions

virtual std::string &placement() = 0

Returns the location within the generated output at which the output text should be inserted.

Returns:

The location.

virtual const std::string &placement() const = 0

Returns the location within the generated output at which the output text should be inserted.

Returns:

The location.

virtual void placement(const std::string &placement) = 0

Sets the location within the generated output at which the output text should be inserted.

Parameters:

placement[in] The location.

virtual void placement(std::string &&placement) = 0

Sets the location within the generated output at which the output text should be inserted.

Parameters:

placement[in] The location.

virtual std::string &text() = 0

Returns the literal output text.

Returns:

The text.

virtual const std::string &text() const = 0

Returns the literal output text.

Returns:

The text.

virtual void text(const std::string &text) = 0

Sets the literal output text.

Parameters:

text[in] The text.

virtual void text(std::string &&text) = 0

Sets the literal output text.

Parameters:

text[in] The text.

virtual ReturnCode_t copy_from(traits<VerbatimTextDescriptor>::ref_type descriptor) = 0

Overwrites the contents of this descriptor with those of another descriptor.

Parameters:

descriptor[in] reference.

Return values:
  • RETCODE_OK – when the copy was successful.

  • RETCODE_BAD_PARAMETER – when descriptor reference is nil.

Returns:

ReturnCode_t

virtual bool equals(traits<VerbatimTextDescriptor>::ref_type descriptor) = 0

Compares.

Parameters:

descriptor[in] reference to compare to.

Returns:

bool true on equality

virtual bool is_consistent() = 0

Indicates whether the states of all of this descriptor’s properties are consistent.

Returns:

bool true if consistent.

20.1.6.2. InvalidArgumentError
class InvalidArgumentError : public eprosima::fastdds::dds::xtypes::Exception, public invalid_argument

Application is passing an invalid argument.

Public Functions

virtual const char *what() const

Retrieve information about the exception that was thrown.

Returns:

Exception information.

20.1.6.3. Type Representation
20.1.6.3.1. TypeObjectRegistry
class ITypeObjectRegistry

Public Functions

virtual ReturnCode_t register_type_object(const std::string &type_name, const CompleteTypeObject &complete_type_object, TypeIdentifierPair &type_ids) = 0

Register a local TypeObject. The MinimalTypeObject is generated from the CompleteTypeObject, and both are registered into the registry with the corresponding TypeIdentifiers and TypeObject serialized sizes.

Parameters:
  • type_name[in] Name of the type being registered.

  • complete_type_object[in] CompleteTypeObject related to the given type name.

  • type_ids[out] TypeIdentifierPair corresponding to the CompleteTypeObject just registered and the generated MinimalTypeObject.

Pre:

type_name must not be empty.

Pre:

complete_type_object must be consistent (only checked in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_PRECONDITION_NOT_MET if the given type_name is empty or if the type_object is inconsistent.

virtual ReturnCode_t register_type_object(const TypeObject &type_object, TypeIdentifierPair &type_ids) = 0

Register a remote TypeObject. This auxiliary method might register only the minimal TypeObject and TypeIdentifier or register both TypeObjects constructing the minimal from the complete TypeObject information. TypeObject consistency is not checked in this method as the order of the dependencies received by the TypeLookupService is not guaranteed. The consistency is checked by the TypeLookupService after all dependencies are registered.

Parameters:
  • type_object[in] Related TypeObject being registered.

  • type_ids[inout] Returns the registered TypeIdentifier. TypeIdentifierPair::type_identifier1 might be TK_NONE. In other case this function will check it is consistence with the provided TypeObject.

Pre:

TypeIdentifierPair::type_identifier1 discriminator must match TypeObject discriminator or be TK_NONE. TypeIdentifierPair::type_identifier1 consistency is only checked in Debug build mode.

Returns:

ReturnCode_t RETCODE_OK if correctly registered. RETCODE_PRECONDITION_NOT_MET if the discriminators differ. RETCODE_PRECONDITION_NOT_MET if the TypeIdentifier is not consistent with the given TypeObject.

virtual ReturnCode_t register_typeobject_w_dynamic_type(const DynamicType::_ref_type &dynamic_type, TypeIdentifierPair &type_ids) = 0

Register DynamicType TypeObject.

Parameters:
  • dynamic_type[in] DynamicType to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the registered DynamicType TypeObject.

Returns:

ReturnCode_t RETCODE_OK always.

virtual ReturnCode_t register_type_identifier(const std::string &type_name, TypeIdentifierPair &type_identifier) = 0

Register an indirect hash TypeIdentifier.

Parameters:
  • type_name[in] Name of the type being registered.

  • type_identifier[inout] TypeIdentifierPair related to the given type name. It must be set in TypeIdentifierPair::type_identifier1. At the end this object is filled with both TypeIdentifiers.

Pre:

TypeIdentifier must not be a direct hash TypeIdentifier.

Pre:

TypeIdentifier must be consistent (only checked in Debug build mode).

Pre:

type_name must not be empty.

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_PRECONDITION_NOT_MET if the given TypeIdentifier is inconsistent or a direct hash TypeIdentifier or if the given type_name is empty.

virtual ReturnCode_t get_type_objects(const std::string &type_name, TypeObjectPair &type_objects) = 0

Get the TypeObjects related to the given type name.

Parameters:
  • type_name[in] Name of the type being queried.

  • type_objects[out] Both complete and minimal TypeObjects related with the given type_name.

Pre:

type_name must not be empty.

Returns:

ReturnCode_t RETCODE_OK if the TypeObjects are found in the registry. RETCODE_NO_DATA if the given type_name has not been registered. RETCODE_BAD_PARAMETER if the type_name correspond to a indirect hash TypeIdentifier. RETCODE_PRECONDITION_NOT_MET if the type_name is empty.

virtual ReturnCode_t get_type_identifiers(const std::string &type_name, TypeIdentifierPair &type_identifiers) = 0

Get the TypeIdentifiers related to the given type name.

Parameters:
  • type_name[in] Name of the type being queried.

  • type_identifiers[out] For direct hash TypeIdentifiers, both minimal and complete TypeIdentifiers are returned. For indirect hash TypeIdentifiers, only the corresponding TypeIdentifier is returned

Pre:

type_name must not be empty.

Returns:

ReturnCode_t RETCODE_OK if the TypeIdentifiers are found in the registry. RETCODE_NO_DATA if the type_name has not been registered. RETCODE_PRECONDITION_NOT_MET if the type_name is empty.

virtual ReturnCode_t get_type_object(const TypeIdentifier &type_identifier, TypeObject &type_object) = 0

Get the TypeObject related to the given TypeIdentifier.

Parameters:
  • type_identifier[in] TypeIdentifier being queried.

  • type_object[out] TypeObject related with the given TypeIdentifier.

Pre:

TypeIdentifier must be a direct hash TypeIdentifier.

Returns:

ReturnCode_t RETCODE_OK if the TypeObject is found within the registry. RETCODE_NO_DATA if the given TypeIdentifier is not found in the registry. RETCODE_PRECONDITION_NOT_MET if the TypeIdentifier is not a direct hash.

virtual ReturnCode_t get_type_information(const TypeIdentifierPair &type_ids, TypeInformation &type_information, bool with_dependencies = false) = 0

Get the TypeInformation related to a specific type_name.

Parameters:
  • type_ids[in] TypeIdentifierPair which type information is queried.

  • type_information[out] Related TypeInformation for the given TypeIdentifier.

  • with_dependencies[in]

Pre:

type_ids must not be empty.

Returns:

ReturnCode_t RETCODE_OK if the type_ids are found within the registry. RETCODE_NO_DATA if the given type_ids is not found. RETCODE_BAD_PARAMETER if the given TypeIdentifier corresponds to a indirect hash TypeIdentifier. RETCODE_PRECONDITION_NOT_MET if any type_ids is empty.

20.1.6.3.2. TypeObjectUtils
class TypeObjectUtils

Public Static Functions

static const TypeObjectHashId build_type_object_hash_id(uint8_t discriminator, const EquivalenceHash &hash)

Build TypeObjectHashId instance.

Parameters:
  • discriminator[in] TypeObjectHashId discriminator to be set.

  • hash[in] StronglyConnectedComponent equivalence hash to be set.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given discriminator is not EK_COMPLETE/EK_MINIMAL.

Returns:

const TypeObjectHashId instance.

static CollectionElementFlag build_collection_element_flag(TryConstructFailAction try_construct_kind, bool external)

Build CollectionElementFlag instance.

Parameters:
  • try_construct_kind[in] try_construct annotation value.

  • external[in] external annotation value.

Returns:

CollectionElementFlag instance.

static StructMemberFlag build_struct_member_flag(TryConstructFailAction try_construct_kind, bool optional, bool must_understand, bool key, bool external)

Build StructMemberFlag instance.

Parameters:
  • try_construct_kind[in] try_construct annotation value.

  • optional[in] optional annotation value.

  • must_understand[in] must_understand annotation value.

  • key[in] key annotation value.

  • external[in] external annotation value.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if both key and optional flags are enabled.

Returns:

StructMemberFlag instance.

static UnionMemberFlag build_union_member_flag(TryConstructFailAction try_construct_kind, bool default_member, bool external)

Build UnionMemberFlag instance.

Parameters:
  • try_construct_kind[in] try_construct annotation value.

  • default_member[in] is default member.

  • external[in] external annotation value.

Returns:

UnionMemberFlag instance.

static UnionDiscriminatorFlag build_union_discriminator_flag(TryConstructFailAction try_construct_kind, bool key)

Build UnionDiscriminatorFlag instance.

Parameters:
  • try_construct_kind[in] try_construct annotation value.

  • key[in] key annotation value.

Returns:

UnionDiscriminatorFlag instance.

static EnumeratedLiteralFlag build_enumerated_literal_flag(bool default_literal)

Build EnumeratedLiteralFlag instance.

Parameters:

default_literal[in] default_literal annotation value.

Returns:

EnumeratedLiteralFlag instance.

static StructTypeFlag build_struct_type_flag(ExtensibilityKind extensibility_kind, bool nested, bool autoid_hash)

Build StructTypeFlag instance.

AnnotationParameterFlag: Unused. No flags apply. AliasMemberFlag: Unused. No flags apply. BitflagFlag: Unused. No flags apply. BitsetMemberFlag: Unused. No flags apply.

Parameters:
  • extensibility_kind[in] extensibility annotation value.

  • nested[in] nested annotation value.

  • autoid_hash[in] autoid annotation has HASH value.

Returns:

StructTypeFlag instance.

static UnionTypeFlag build_union_type_flag(ExtensibilityKind extensibility_kind, bool nested, bool autoid_hash)

Build UnionTypeFlag instance.

Parameters:
  • extensibility_kind[in] extensibility annotation value.

  • nested[in] nested annotation value.

  • autoid_hash[in] autoid annotation has HASH value.

Returns:

UnionTypeFlag instance.

static const StringSTypeDefn build_string_s_type_defn(SBound bound)

Build StringSTypeDefn instance.

CollectionTypeFlag: Unused. No flags apply. AnnotationTypeFlag: Unused. No flags apply. AliasTypeFlag: Unused. No flags apply. EnumTypeFlag: Unused. No flags apply. BitmaskTypeFlag: Unused. No flags apply. BitsetTypeFlag: Unused. No flags apply.

Parameters:

bound[in] Bound for the small string/wstring.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if bound is 0.

Pre:

bound > 0 (INVALID_SBOUND)

Returns:

const StringSTypeDefn instance.

static const StringLTypeDefn build_string_l_type_defn(LBound bound)

Build StringLTypeDefn instance.

Parameters:

bound[in] Bound for the large string/wstring.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if bound is lower than 256.

Pre:

bound > 255

Returns:

const StringLTypeDefn instance.

static const PlainCollectionHeader build_plain_collection_header(EquivalenceKind equiv_kind, CollectionElementFlag element_flags)

Build PlainCollectionHeader instance.

Parameters:
  • equiv_kind[in] EquivalenceKind: EK_MINIMAL/EK_COMPLETE/EK_BOTH

  • element_flags[in] CollectionElementFlags to be set. This element must be constructed with the corresponding builder to ensure its consistency.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – if the given element_flags are inconsistent. This exception is only thrown in Debug build mode.

Returns:

const PlainCollectionHeader instance.

static const PlainSequenceSElemDefn build_plain_sequence_s_elem_defn(const PlainCollectionHeader &header, SBound s_bound, const eprosima::fastcdr::external<TypeIdentifier> &element_identifier)

Build PlainSequenceSElemDefn instance.

Parameters:
  • header[in] PlainCollectionHeader to be set.

  • s_bound[in] Sequence bound.

  • element_identifier[in] Sequence element TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception

  1. The given bound is 0.

  2. The given TypeIdentifier EquivalenceKind is not consistent with the one contained in the header.

  3. Inconsistent header (only in Debug build mode).

  4. Inconsistent element_identifier (only in Debug build mode).

Pre:

bound > 0 (INVALID_SBOUND)

Pre:

element_identifier has been initialized.

Returns:

const PlainSequenceSElemDefn instance.

static const PlainSequenceLElemDefn build_plain_sequence_l_elem_defn(const PlainCollectionHeader &header, LBound l_bound, const eprosima::fastcdr::external<TypeIdentifier> &element_identifier)

Build PlainSequenceLElemDefn instance.

Parameters:
  • header[in] PlainCollectionHeader to be set.

  • l_bound[in] Sequence bound.

  • element_identifier[in] Sequence element TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception

  1. Bound lower than 256.

  2. The given TypeIdentifier EquivalenceKind is not consistent with the one contained in the header.

  3. Inconsistent header (only in Debug build mode).

  4. Inconsistent element_identifier (only in Debug build mode).

Pre:

bound > 255

Pre:

element_identifier has been initialized.

Returns:

const PlainSequenceLElemDefn instance.

template<typename element>
static inline void add_array_dimension(std::vector<element> &array_bound_seq, element dimension_bound)

Add dimension bound to the array bound sequence.

Template Parameters:
  • array – Either a SBoundSeq or LBoundSeq.

  • element – Either a SBound or LBound.

Parameters:
  • array_bound_seq[inout] Sequence with the array bounds.

  • dimension_bound[in] Dimension bound to be added into the sequence.

static const PlainArraySElemDefn build_plain_array_s_elem_defn(const PlainCollectionHeader &header, const SBoundSeq &array_bound_seq, const eprosima::fastcdr::external<TypeIdentifier> &element_identifier)

Build PlainArraySElemDefn instance.

Parameters:
  • header[in] PlainCollectionHeader to be set.

  • array_bound_seq[in] Bounds for the array dimensions.

  • element_identifier[in] Array element TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception

  1. Any given bound in array_bound_seq is 0.

  2. The given TypeIdentifier EquivalenceKind is not consistent with the one contained in the header.

  3. Inconsistent header (only in Debug build mode).

  4. Inconsistent element_identifier (only in Debug build mode).

Pre:

Any element in array_bound_seq must be greater than 0 (INVALID_SBOUND)

Pre:

element_identifier has been initialized.

Returns:

const PlainArraySElemDefn instance.

static const PlainArrayLElemDefn build_plain_array_l_elem_defn(const PlainCollectionHeader &header, const LBoundSeq &array_bound_seq, const eprosima::fastcdr::external<TypeIdentifier> &element_identifier)

Build PlainArrayLElemDefn instance.

Parameters:
  • header[in] PlainCollectionHeader to be set.

  • array_bound_seq[in] Bounds for the array dimensions.

  • element_identifier[in] Array element TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception

  1. Any given bound in array_bound_seq is 0.

  2. There is no dimension with a bound greater than 255.

  3. The given TypeIdentifier EquivalenceKind is not consistent with the one contained in the header.

  4. Inconsistent header (only in Debug build mode).

  5. Inconsistent element_identifier (only in Debug build mode).

Pre:

At least one element of array_bound_seq must be greater than 255 and no element must be 0 (INVALID_SBOUND)

Pre:

element_identifier has been initialized.

Returns:

const PlainArrayLElemDefn instance.

static const PlainMapSTypeDefn build_plain_map_s_type_defn(const PlainCollectionHeader &header, const SBound bound, const eprosima::fastcdr::external<TypeIdentifier> &element_identifier, const CollectionElementFlag key_flags, const eprosima::fastcdr::external<TypeIdentifier> &key_identifier)

Build PlainMapSTypeDefn instance.

Parameters:
  • header[in] PlainCollectionHeader to be set.

  • bound[in] Map bound.

  • element_identifier[in] Map element TypeIdentifier.

  • key_flags[in] Flags applying to map key.

  • key_identifier[in] Map key TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception

  1. Given bound is zero (INVALID_SBOUND)

  2. Inconsistent element_identifier EquivalenceKind with the one contained in the header.

  3. Direct hash key_identifier or indirect hash TypeIdentifier with exception to string/wstring. XTypes v1.3 Clause 7.2.2.4.3: Implementers of this specification need only support key elements of signed and unsigned integer types and of narrow and wide string types.

  4. Inconsistent key_flags.

  5. Inconsistent header (only in Debug build mode).

  6. Inconsistent element_identifier or key_identifier (only in Debug build mode).

Pre:

bound > 0 (INVALID_SBOUND)

Pre:

Both element_identifier and key_identifier have been initialized.

Returns:

const PlainMapSTypeDefn instance.

static const PlainMapLTypeDefn build_plain_map_l_type_defn(const PlainCollectionHeader &header, const LBound bound, const eprosima::fastcdr::external<TypeIdentifier> &element_identifier, const CollectionElementFlag key_flags, const eprosima::fastcdr::external<TypeIdentifier> &key_identifier)

Build PlainMapLTypeDefn instance.

Parameters:
  • header[in] PlainCollectionHeader to be set.

  • bound[in] Map bound.

  • element_identifier[in] Map element TypeIdentifier.

  • key_flags[in] Flags applying to map key.

  • key_identifier[in] Map key TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception

  1. Given bound is lower than 256

  2. Inconsistent element_identifier EquivalenceKind with the one contained in the header.

  3. Direct hash key_identifier or indirect hash TypeIdentifier with exception to string/wstring. XTypes v1.3 Clause 7.2.2.4.3: Implementers of this specification need only support key elements of signed and unsigned integer types and of narrow and wide string types.

  4. Inconsistent key_flags.

  5. Inconsistent header (only in Debug build mode).

  6. Inconsistent element_identifier or key_identifier (only in Debug build mode).

Pre:

bound > 255

Pre:

Both element_identifier and key_identifier have been initialized.

Returns:

const PlainMapLTypeDefn instance.

static const StronglyConnectedComponentId build_strongly_connected_component_id(const TypeObjectHashId &sc_component_id, int32_t scc_length, int32_t scc_index)

Build StronglyConnectedComponentId instance.

Parameters:
  • sc_component_id[in] Strongly Connected Component (SCC) ID.

  • scc_length[in] Number of components within SCC.

  • scc_index[in] Identify specific component within SCC.

Returns:

const StronglyConnectedComponentId instance.

static const ExtendedTypeDefn build_extended_type_defn()

Build ExtendedTypeDefn instance (empty. Available for future extension).

Returns:

const ExtendedTypeDefn instance.

static ReturnCode_t build_and_register_s_string_type_identifier(const StringSTypeDefn &string, const std::string &type_name, TypeIdentifierPair &type_ids, bool wstring = false)

Register small string/wstring TypeIdentifier into TypeObjectRegistry.

Primitive types are registered when TypeObjectRegistry is instantiated.

Parameters:
  • string[in] StringSTypeDefn union member to set.

  • type_name[in] Type name to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the StringSTypeDefn just registered.

  • wstring[in] Flag to build a wstring. Default false.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given member is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_l_string_type_identifier(const StringLTypeDefn &string, const std::string &type_name, TypeIdentifierPair &type_ids, bool wstring = false)

Register large string/wstring TypeIdentifier into TypeObjectRegistry.

Parameters:
  • string[in] StringLTypeDefn union member to set.

  • type_name[in] Type name to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the StringLTypeDefn just registered.

  • wstring[in] Flag to build a wstring. Default false.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given member is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_s_sequence_type_identifier(const PlainSequenceSElemDefn &plain_seq, const std::string &type_name, TypeIdentifierPair &type_ids)

Register small sequence TypeIdentifier into TypeObjectRegistry.

Parameters:
  • plain_seq[in] PlainSequenceSElemDefn union member to set.

  • type_name[in] Type name to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the PlainSequenceSElemDefn just registered.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given member is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_l_sequence_type_identifier(const PlainSequenceLElemDefn &plain_seq, const std::string &type_name, TypeIdentifierPair &type_ids)

Register large sequence TypeIdentifier into TypeObjectRegistry.

Parameters:
  • plain_seq[in] PlainSequenceLElemDefn union member to set.

  • type_name[in] Type name to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the PlainSequenceLElemDefn just registered.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given member is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_s_array_type_identifier(const PlainArraySElemDefn &plain_array, const std::string &type_name, TypeIdentifierPair &type_ids)

Register small array TypeIdentifier into TypeObjectRegistry.

Parameters:
  • plain_array[in] PlainArraySElemDefn union member to set.

  • type_name[in] Type name to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the PlainArraySElemDefn just registered.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given member is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_l_array_type_identifier(const PlainArrayLElemDefn &plain_array, const std::string &type_name, TypeIdentifierPair &type_ids)

Register large array TypeIdentifier into TypeObjectRegistry.

Parameters:
  • plain_array[in] PlainArrayLElemDefn union member to set.

  • type_name[in] Type name to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the PlainArrayLElemDefn just registered.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given member is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_s_map_type_identifier(const PlainMapSTypeDefn &plain_map, const std::string &type_name, TypeIdentifierPair &type_ids)

Register small map TypeIdentifier into TypeObjectRegistry.

Parameters:
  • plain_map[in] PlainMapSTypeDefn union member to set.

  • type_name[in] Type name to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the PlainMapSTypeDefn just registered.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given member is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_l_map_type_identifier(const PlainMapLTypeDefn &plain_map, const std::string &type_name, TypeIdentifierPair &type_ids)

Register large map TypeIdentifier into TypeObjectRegistry.

Parameters:
  • plain_map[in] PlainMapLTypeDefn union member to set.

  • type_name[in] Type name to be registered.

  • type_ids[out] TypeIdentifierPair corresponding to the PlainMapLTypeDefn just registered.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given member is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_scc_type_identifier(const StronglyConnectedComponentId &scc, const std::string &type_name)

Register StronglyConnectedComponent TypeIdentifier into TypeObjectRegistry.

Parameters:
  • scc[in] StronglyConnectedComponent union member to set.

  • type_name[in] Type name to be registered.

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeIdentifier registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static const ExtendedAnnotationParameterValue build_extended_annotation_parameter_value()

Build ExtendedAnnotationParameterValue instance (empty. Available for future extension).

Returns:

const ExtendedAnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(bool boolean_value)

Build AnnotationParameterValue instance.

Parameters:

boolean_value[in] Boolean value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value_byte(uint8_t byte_value)

Build AnnotationParameterValue instance.

Parameters:

byte_value[in] Byte value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(int8_t int8_value)

Build AnnotationParameterValue instance.

Parameters:

int8_value[in] Int8 value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(uint8_t uint8_value)

Build AnnotationParameterValue instance.

Parameters:

uint8_value[in] Unsigned int8 value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(int16_t int16_value)

Build AnnotationParameterValue instance.

Parameters:

int16_value[in] Short value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(uint16_t uint16_value)

Build AnnotationParameterValue instance.

Parameters:

uint16_value[in] Unsigned short value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(int32_t int32_value)

Build AnnotationParameterValue instance.

Parameters:

int32_value[in] Long value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(uint32_t uint32_value)

Build AnnotationParameterValue instance.

Parameters:

uint32_value[in] Unsigned long value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(int64_t int64_value)

Build AnnotationParameterValue instance.

Parameters:

int64_value[in] Long long value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(uint64_t uint64_value)

Build AnnotationParameterValue instance.

Parameters:

uint64_value[in] Unsigned long long value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(float float32_value)

Build AnnotationParameterValue instance.

Parameters:

float32_value[in] Float value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(double float64_value)

Build AnnotationParameterValue instance.

Parameters:

float64_value[in] Double value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(long double float128_value)

Build AnnotationParameterValue instance.

Parameters:

float128_value[in] Long double value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(char char_value)

Build AnnotationParameterValue instance.

Parameters:

char_value[in] Char value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(wchar_t wchar_value)

Build AnnotationParameterValue instance.

Parameters:

wchar_value[in] Wide char value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value_enum(int32_t enumerated_value)

Build AnnotationParameterValue instance.

Parameters:

enumerated_value[in] Enumerated value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(const eprosima::fastcdr::fixed_string<128> &string8_value)

Build AnnotationParameterValue instance.

Parameters:

string8_value[in] String value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AnnotationParameterValue build_annotation_parameter_value(const std::wstring &string16_value)

Build AnnotationParameterValue instance.

Parameters:

string16_value[in] Wide string value to set in the union.

Returns:

const AnnotationParameterValue instance.

static const AppliedAnnotationParameter build_applied_annotation_parameter(const NameHash &paramname_hash, const AnnotationParameterValue &value)

Build AppliedAnnotationParameter instance.

Parameters:
  • paramname_hash[in] Parameter name hash.

  • value[in] Parameter value.

Returns:

const AppliedAnnotationParameter instance.

static void add_applied_annotation_parameter(AppliedAnnotationParameterSeq &param_seq, const AppliedAnnotationParameter &param)

Add AppliedAnnotationParameter to the sequence.

Parameters:
  • param_seq[inout] AppliedAnnotationParameter sequence to be modified.

  • param[in] AppliedAnnotationParameter to be added.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the parameter being added has already been included in the sequence.

static const AppliedAnnotation build_applied_annotation(const TypeIdentifier &annotation_typeid, const eprosima::fastcdr::optional<AppliedAnnotationParameterSeq> &param_seq)

Build AppliedAnnotation instance.

Parameters:
  • annotation_typeid[in] Annotation TypeIdentifier.

  • param_seq[in] Annotation parameters.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given annotation_typeid TypeIdentifier does not correspond to an annotation TypeObject (only in Debug build mode).

  2. Given AppliedAnnotationParameterSeq is inconsistent (only in Debug build mode).

  3. Given annotation TypeIdentifier corresponds to a builtin annotation and the given parameters are inconsistent (only in Debug build mode).

Returns:

const AppliedAnnotation instance.

static void add_applied_annotation(AppliedAnnotationSeq &ann_custom_seq, const AppliedAnnotation &ann_custom)

Add AppliedAnnotation to the sequence.

Parameters:
  • ann_custom_seq[inout] AppliedAnnotation sequence to be modified.

  • ann_custom[in] AppliedAnnotation to be added.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given AppliedAnnotation is not consistent (only in Debug build mode).

  2. Given AppliedAnnotation is already present in the sequence.

static const AppliedVerbatimAnnotation build_applied_verbatim_annotation(PlacementKind placement, const eprosima::fastcdr::fixed_string<32> &language, const std::string &text)

Build AppliedVerbatimAnnotation instance.

Parameters:
  • placement[in] Verbatim annotation placement parameter.

  • language[in] Verbatim annotation language parameter.

  • text[in] Verbatim annotation text parameter.

Returns:

const AppliedVerbatimAnnotation instance.

static const AppliedBuiltinMemberAnnotations build_applied_builtin_member_annotations(const eprosima::fastcdr::optional<std::string> &unit, const eprosima::fastcdr::optional<AnnotationParameterValue> &min, const eprosima::fastcdr::optional<AnnotationParameterValue> &max, const eprosima::fastcdr::optional<std::string> &hash_id)

Build AppliedBuiltinMemberAnnotations instance.

Parameters:
  • unit[in] Unit annotation value.

  • min[in] Min annotation value.

  • max[in] Max annotation value.

  • hash_id[in] Hashid annotation value.

Returns:

const AppliedBuiltinMemberAnnotations instance.

static const CommonStructMember build_common_struct_member(MemberId member_id, StructMemberFlag member_flags, const TypeIdentifier &member_type_id)

Build CommonStructMember instance.

Parameters:
  • member_id[in] Member identifier.

  • member_flags[in] Member flags: optional, must_understand, key, and external.

  • member_type_id[in] Member TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception:

  1. The given flags are not consistent (only in Debug build mode).

  2. The given TypeIdentifier is not consistent (only in Debug build mode).

Returns:

const CommonStructMember instance.

static const CompleteMemberDetail build_complete_member_detail(const MemberName &name, const eprosima::fastcdr::optional<AppliedBuiltinMemberAnnotations> &ann_builtin, const eprosima::fastcdr::optional<AppliedAnnotationSeq> &ann_custom)

Build CompleteMemberDetail instance.

Parameters:
  • name[in] Member name.

  • ann_builtin[in] Member builtin annotations.

  • ann_custom[in] Member custom annotations.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Empty member name.

  2. Given AppliedAnnotationSeq is not consistent (only Debug build mode).

Returns:

const CompleteMemberDetail instance.

static const CompleteStructMember build_complete_struct_member(const CommonStructMember &common, const CompleteMemberDetail &detail)

Build CompleteStructMember instance.

MinimalMemberDetail constructed from CompleteMemberDetail

Parameters:
  • common[in] CommonStructMember to be set.

  • detail[in] CompleteMemberDetail to be set.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonStructMember is inconsistent (only Debug build mode).

  2. Given CompleteMemberDetail is inconsistent (only Debug build mode).

Returns:

const CompleteMemberDetail instance.

static void add_complete_struct_member(CompleteStructMemberSeq &member_seq, const CompleteStructMember &member)

Add CompleteStructMember to the sequence.

Parameters:
  • member_seq[inout] CompleteStructMember sequence to be modified.

  • member[in] CompleteStructMember to be added.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CompleteStructMember is not consistent (only in Debug build mode).

  2. There is already another member in the sequence with the same member id or the same member name (only in Debug build mode).

static const AppliedBuiltinTypeAnnotations build_applied_builtin_type_annotations(const eprosima::fastcdr::optional<AppliedVerbatimAnnotation> &verbatim)

Build AppliedBuiltinTypeAnnotations instance.

MinimalStructMember constructed from CompleteStructMember

Parameters:

verbatim[in] AppliedVerbatimAnnotation to be set.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given verbatim annotation is inconsistent (only in Debug build mode).

Returns:

const AppliedBuiltinTypeAnnotations instance.

static const CompleteTypeDetail build_complete_type_detail(const eprosima::fastcdr::optional<AppliedBuiltinTypeAnnotations> &ann_builtin, const eprosima::fastcdr::optional<AppliedAnnotationSeq> &ann_custom, const QualifiedTypeName &type_name)

Build CompleteTypeDetail instance.

MinimalTypeDetail constructed from CompleteTypeDetail: empty. Available for future extension.

Parameters:
  • ann_builtin[in] Verbatim annotation.

  • ann_custom[in] Applied annotations.

  • type_name[in] Name of the type.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. any applied annotation is not consistent (only Debug build mode).

Returns:

const CompleteTypeDetail instance.

static const CompleteStructHeader build_complete_struct_header(const TypeIdentifier &base_type, const CompleteTypeDetail &detail)

Build CompleteStructHeader instance.

Parameters:
  • base_type[in] TypeIdentifier of the parent structure (inheritance).

  • detail[in] CompleteTypeDetail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given TypeIdentifier is not consistent (direct HASH or empty TypeIdentifier). In Debug build mode the corresponding TypeObject is also checked in case of direct HASH TypeIdentifier.

  2. Given CompleteTypeDetail is not consistent (only in Debug build mode).

Returns:

const CompleteStructHeader instance.

static const CompleteStructType build_complete_struct_type(StructTypeFlag struct_flags, const CompleteStructHeader &header, const CompleteStructMemberSeq &member_seq)

Build CompleteStructType instance.

MinimalStructHeader constructed from CompleteStructHeader.

Parameters:
  • struct_flags[in] StructTypeFlags.

  • header[in] CompleteStructHeader.

  • member_seq[in] Sequence of CompleteStructMembers.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given StructTypeFlag is not consistent (only in Debug build mode).

  2. Given CompleteStructHeader is not consistent (only in Debug build mode).

  3. Given CompleteStructMemberSeq is not consistent (only in Debug build mode).

  4. Given flags are not consistent with the builtin annotations.

Returns:

const CompleteStructType instance.

static void add_union_case_label(UnionCaseLabelSeq &label_seq, int32_t label)

Add label to the union case label sequence.

MinimalStructType constructed from CompleteStructType.

Parameters:
  • label_seq[inout] Sequence to be modified.

  • label[in] Label to be added.

static const CommonUnionMember build_common_union_member(MemberId member_id, UnionMemberFlag member_flags, const TypeIdentifier &type_id, const UnionCaseLabelSeq &label_seq)

Build CommonUnionMember instance.

Parameters:
  • member_id[in] Member identifier.

  • member_flags[in] Member flags.

  • type_id[in] Member TypeIdentifier.

  • label_seq[in] Member applicable case labels.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given UnionMemberFlags are not consistent (only Debug build mode).

  2. Given TypeIdentifier is not consistent (only Debug build mode).

Returns:

const CommonUnionMember instance.

static const CompleteUnionMember build_complete_union_member(const CommonUnionMember &common, const CompleteMemberDetail &detail)

Build CompleteUnionMember instance.

Parameters:
  • common[in] CommonUnionMember.

  • detail[in] CompleteMemberDetail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonUnionMember is not consistent (only in Debug build mode).

  2. Given CompleteMemberDetail is not consistent (only in Debug build mode).

Returns:

const CompleteUnionMember instance.

static void add_complete_union_member(CompleteUnionMemberSeq &complete_union_member_seq, const CompleteUnionMember &member)

Add CompleteUnionMember to sequence.

Parameters:
  • complete_union_member_seq[inout] Sequence to be modified.

  • member[in] Complete union member to be added.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CompleteUnionMember is not consistent (only in Debug build mode).

  2. There is already another member in the sequence with the same member id or the same member name (only in Debug build mode).

  3. If the given member is marked as default, if there is already another member marked as default (only in Debug build mode).

  4. There are repeated union case labels (only in Debug build mode).

  5. Member name is protected (“discriminator”).

static const CommonDiscriminatorMember build_common_discriminator_member(UnionDiscriminatorFlag member_flags, const TypeIdentifier &type_id)

Build CommonDiscriminatorMember instance.

MinimalUnionMember constructed from CompleteUnionMember.

Parameters:
  • member_flags[in] Discriminator flags.

  • type_id[in] Discriminator TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given discriminator flags are inconsistent (only in Debug build mode).

  2. Given TypeIdentifier is not consistent. XTypes v1.3 Clause 7.2.2.4.4.3 The discriminator of a union must be one of the following types: Boolean, Byte, Char8, Char16, Int8, Uint8, Int16, Uint16, Int32, Uint32, Int64, Uint64, any enumerated type, any alias type that resolves, directly or indirectly, to one of the aforementioned types.

Returns:

const CommonDiscriminatorMember instance.

static const CompleteDiscriminatorMember build_complete_discriminator_member(const CommonDiscriminatorMember &common, const eprosima::fastcdr::optional<AppliedBuiltinTypeAnnotations> &ann_builtin, const eprosima::fastcdr::optional<AppliedAnnotationSeq> &ann_custom)

Build CompleteDiscriminatorMember instance.

Parameters:
  • common[in] CommonDiscriminatorMember.

  • ann_builtin[in] Verbatim annotation.

  • ann_custom[in] Applied annotations.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonDiscriminatorMember is inconsistent (only in Debug build mode).

  2. AppliedBuiltinTypeAnnotation is inconsistent (only in Debug build mode).

  3. Any given AppliedAnnotation is inconsistent (only in Debug build mode).

  4. CommonDiscriminatorMember is inconsistent with given builtin annotations.

Returns:

const CompleteDiscriminatorMember instance.

static const CompleteUnionHeader build_complete_union_header(const CompleteTypeDetail &detail)

Build CompleteUnionHeader instance.

MinimalDiscriminatorMember constructed from CompleteDiscriminatorMember.

Parameters:

detail – CompleteTypeDetail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given CompleteTypeDetail is not consistent (only in Debug build mode).

Returns:

const CompleteUnionHeader instance.

static const CompleteUnionType build_complete_union_type(UnionTypeFlag union_flags, const CompleteUnionHeader &header, const CompleteDiscriminatorMember &discriminator, const CompleteUnionMemberSeq &member_seq)

Build CompleteUnionType instance.

MinimalUnionHeader constructed from CompleteUnionHeader.

Parameters:
  • union_flags[in]

  • header[in]

  • discriminator[in]

  • member_seq[in]

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given UnionTypeFlags are not consistent (only in Debug build mode).

  2. Given CompleteUnionHeader is not consistent (only in Debug build mode).

  3. Given CompleteDiscriminatorMember inconsistent (only in Debug build mode).

  4. Given CompleteUnionMemberSeq is not consistent (only in Debug build mode).

  5. Given flags are not consistent with the builtin annotations.

Returns:

const CompleteUnionType instance.

static const CommonAnnotationParameter build_common_annotation_parameter(AnnotationParameterFlag member_flags, const TypeIdentifier &member_type_id)

Build CommonAnnotationParameter instance.

MinimalUnionType constructed from CompleteUnionType.

Parameters:
  • member_flags[in] AnnotationParameterFlag: empty. No flags apply. It must be zero.

  • member_type_id[in] Member TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given AnnotationParameterFlag are not empty.

  2. Given TypeIdentifier is not consistent (only in Debug build mode).

Returns:

const CommonAnnotationParameter instance.

static const CompleteAnnotationParameter build_complete_annotation_parameter(const CommonAnnotationParameter &common, const MemberName &name, const AnnotationParameterValue &default_value)

Build CompleteAnnotationParameter instance.

Parameters:
  • common[in] CommonAnnotationParameter.

  • name[in] Member name.

  • default_value[in] Annotation default value.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonAnnotationParameter is inconsistent (only in Debug build mode).

  2. CommonAnnotationParameter TypeIdentifier is inconsistent with AnnotationParameterValue type.

  3. Given parameter name is empty.

Returns:

const CompleteAnnotationParameter instance.

static void add_complete_annotation_parameter(CompleteAnnotationParameterSeq &sequence, const CompleteAnnotationParameter &param)

Add CompleteAnnotationParameter to sequence.

Parameters:
  • sequence[inout] Sequence to be modified.

  • param[in] Complete annotation parameter to be added.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CompleteAnnotationParameter is not consistent (only in Debug build mode).

  2. There is already another member in the sequence with the same member id or the same member name (only in Debug build mode).

static const CompleteAnnotationHeader build_complete_annotation_header(const QualifiedTypeName &annotation_name)

Build CompleteAnnotationHeader instance.

MinimalAnnotationParameter constructed from CompleteAnnotationParameter.

Parameters:

annotation_name[in] Qualified annotation type name.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – if the annotation_name is empty.

Returns:

const CompleteAnnotationHeader instance.

static const CompleteAnnotationType build_complete_annotation_type(AnnotationTypeFlag annotation_flag, const CompleteAnnotationHeader &header, const CompleteAnnotationParameterSeq &member_seq)

Build CompleteAnnotationType instance.

MinimalAnnotationHeader constructed from CompleteAnnotationHeader: empty. Available for future extension.

Parameters:
  • annotation_flag[in] Unused. No flags apply. It must be 0.

  • header[in] CompleteAnnotationHeader.

  • member_seq[in] CompleteAnnotationParameter sequence.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Any annotation flag is set.

  2. Given header is inconsistent (only in Debug build mode).

  3. Any CompleteAnnotationParameter in the sequence is inconsistent (only in Debug build mode).

Returns:

const CompleteAnnotationType instance.

static const CommonAliasBody build_common_alias_body(AliasMemberFlag related_flags, const TypeIdentifier &related_type)

Build CommonAliasBody instance.

MinimalAnnotationType constructed from CompleteAnnotationType.

Parameters:
  • related_flags[in] AliasMemberFlag: unused. No flags apply. It must be 0.

  • related_type[in] Related TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Any alias member flag is set.

  2. Non-consistent TypeIdentifier (only in Debug build mode).

Returns:

const CommonAliasBody instance.

static const CompleteAliasBody build_complete_alias_body(const CommonAliasBody &common, const eprosima::fastcdr::optional<AppliedBuiltinMemberAnnotations> &ann_builtin, const eprosima::fastcdr::optional<AppliedAnnotationSeq> &ann_custom)

Build CompleteAliasBody instance.

Parameters:
  • common[in] CommonAliasBody.

  • ann_builtin[in] Applied builtin member annotations: unit, max, min, range, hashid

  • ann_custom[in] Applied custom annotations

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonAliasBody is inconsistent (only Debug build mode).

  2. AppliedAnnotationSeq is inconsistent (only Debug build mode).

  3. hashid builtin annotation is set.

Returns:

const CompleteAliasBody instance.

static const CompleteAliasHeader build_complete_alias_header(const CompleteTypeDetail &detail)

Build CompleteAliasHeader instance.

MinimalAliasBody constructed from CompleteAliasBody.

Parameters:

detail[in] Complete type detail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given CompleteTypeDetail is inconsistent (only in Debug build mode).

Returns:

const CompleteAliasHeader instance.

static const CompleteAliasType build_complete_alias_type(AliasTypeFlag alias_flags, const CompleteAliasHeader &header, const CompleteAliasBody &body)

Build CompleteAliasType instance.

MinimalAliasHeader constructed from CompleteAliasHeader: empty. Available for future extension.

Parameters:
  • alias_flags[in] Alias type flags: unused. No flags apply. It must be zero.

  • header[in] CompleteAliasHeader.

  • body[in] CompleteAliasBody.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Any alias type flag is set.

  2. Inconsistent header and/or body (only in Debug build mode).

Returns:

const CompleteAliasType instance.

static const CompleteElementDetail build_complete_element_detail(const eprosima::fastcdr::optional<AppliedBuiltinMemberAnnotations> &ann_builtin, const eprosima::fastcdr::optional<AppliedAnnotationSeq> &ann_custom)

Build CompleteElementDetail instance.

MinimalAliasType constructed from CompleteAliasType.

Parameters:
  • ann_builtin[in] Applied builtin member annotations: unit, max, min, range, hashid

  • ann_custom[in] Applied custom annotations

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. AppliedAnnotationSeq is inconsistent (only Debug build mode).

  2. hashid builtin annotation is applied.

Returns:

const CompleteElementDetail instance.

static const CommonCollectionElement build_common_collection_element(CollectionElementFlag element_flags, const TypeIdentifier &type)

Build CommonCollectionElement instance.

Parameters:
  • element_flags[in] CollectionElementFlag.

  • type[in] TypeIdentifier.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given collection element flags are not consistent (only in Debug build mode).

  2. Given TypeIdentifier is not consistent (only in Debug build mode).

Returns:

const CommonCollectionElement instance

static const CompleteCollectionElement build_complete_collection_element(const CommonCollectionElement &common, const CompleteElementDetail &detail)

Build CompleteCollectionElement instance.

Parameters:
  • common[in] CommonCollectionElement.

  • detail[in] CompleteElementDetail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonCollectionElement is not consistent (only in Debug build mode).

  2. Given CompleteElementDetail is not consistent (only in Debug build mode).

Returns:

const CompleteCollectionElement instance

static const CommonCollectionHeader build_common_collection_header(LBound bound)

Build CommonCollectionHeader instance.

MinimalCollectionElement constructed from CompleteCollectionElement.

Parameters:

bound[in] Collection bound.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given bound is not consistent.

Returns:

const CommonCollectionHeader instance.

static const CompleteCollectionHeader build_complete_collection_header(const CommonCollectionHeader &common, const eprosima::fastcdr::optional<CompleteTypeDetail> &detail)

Build CompleteCollectionHeader instance.

Parameters:
  • common[in] CommonCollectionHeader

  • detail[in] CompleteTypeDetail

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonCollectionHeader is inconsistent (only in Debug build mode).

  2. Given CompleteTypeDetail is inconsistent (only in Debug build mode).

Returns:

const CompleteCollectionHeader instance.

static const CompleteSequenceType build_complete_sequence_type(CollectionTypeFlag collection_flag, const CompleteCollectionHeader &header, const CompleteCollectionElement &element)

Build CompleteSequenceType instance.

MinimalCollectionHeader constructed from CompleteCollectionHeader.

Parameters:
  • collection_flag[in] collection type flag: unused. No flags apply. It must be 0.

  • header[in] CompleteCollectionHeader.

  • element[in] CompleteCollectionElement.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Any collection flag is set.

  2. Given header is inconsistent (only in Debug build mode).

  3. Given element is inconsistent (only in Debug build mode).

Returns:

const CompleteSequenceType instance

static const CommonArrayHeader build_common_array_header(const LBoundSeq &bound_seq)

Build CommonArrayHeader instance.

MinimalSequenceType constructed from CompleteSequenceType.

Parameters:

bound_seq[in] Sequence of the dimension’s bounds.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if any given bound is 0 (invalid).

Returns:

const CommonArrayHeader instance.

static const CompleteArrayHeader build_complete_array_header(const CommonArrayHeader &common, const CompleteTypeDetail &detail)

Build CompleteArrayHeader instance.

Parameters:
  • common[in] CommonArrayHeader.

  • detail[in] CompleteTypeDetail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonArrayHeader is inconsistent (only in Debug build mode).

  2. Given CompleteTypeDetail is inconsistent (only in Debug build mode).

Returns:

const CompleteArrayHeader instance.

static const CompleteArrayType build_complete_array_type(CollectionTypeFlag collection_flag, const CompleteArrayHeader &header, const CompleteCollectionElement &element)

Build CompleteArrayType instance.

MinimalArrayHeader constructed from CompleteArrayHeader.

Parameters:
  • collection_flag[in] collection type flag: unused. No flags apply. It must be 0.

  • header[in] CompleteArrayHeader.

  • element[in] CompleteCollectionElement.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Any collection flag is set.

  2. Given header is inconsistent (only in Debug build mode).

  3. Given element is inconsistent (only in Debug build mode).

Returns:

const CompleteArrayType instance.

static const CompleteMapType build_complete_map_type(CollectionTypeFlag collection_flag, const CompleteCollectionHeader &header, const CompleteCollectionElement &key, const CompleteCollectionElement &element)

Build CompleteMapType instance.

MinimalArrayType constructed from CompleteArrayType.

Parameters:
  • collection_flag[in] collection type flag: unused. No flags apply. It must be 0.

  • header[in] CompleteArrayHeader.

  • key[in] CompleteCollectionElement describing map key.

  • element[in] CompleteCollectionElement describing map element.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Any collection flag is set.

  2. Given header is inconsistent (only in Debug build mode).

  3. Given key TypeIdentifier is inconsistent.

  4. Given key description is inconsistent (only in Debug build mode).

  5. Given element is inconsistent (only in Debug build mode).

Returns:

const CompleteMapType instance.

static const CommonEnumeratedLiteral build_common_enumerated_literal(int32_t value, EnumeratedLiteralFlag flags)

Build CommonEnumeratedLiteral instance.

MinimalMapType constructed from CompleteMapType.

Parameters:
  • value[in] Enumerated literal value.

  • flags[in] Enumerated literal flags: only default flag apply.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if any other flag different from default is set (only in Debug build mode).

Returns:

const CommonEnumeratedLiteral instance.

static const CompleteEnumeratedLiteral build_complete_enumerated_literal(const CommonEnumeratedLiteral &common, const CompleteMemberDetail &detail)

Build CompleteEnumeratedLiteral instance.

Parameters:
  • common[in] CommonEnumeratedLiteral.

  • detail[in] CompleteMemberDetail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonEnumeratedLiteral is inconsistent (only in Debug build mode).

  2. Given CompleteMemberDetail is inconsistent (only in Debug build mode).

Returns:

const CompleteEnumeratedLiteral instance.

static void add_complete_enumerated_literal(CompleteEnumeratedLiteralSeq &sequence, const CompleteEnumeratedLiteral &enum_literal)

Add CompleteEnumeratedLiteral to sequence.

Parameters:
  • sequence[in] Sequence to be modified.

  • enum_literal[inout] CompleteEnumeratedLiteral to be added.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonEnumeratedLiteral is not consistent (only in Debug build mode).

  2. There is already another literal in the sequence with the same value or the same member name (only in Debug build mode).

static const CommonEnumeratedHeader build_common_enumerated_header(BitBound bit_bound, bool bitmask = false)

Build CommonEnumeratedHeader instance.

MinimalEnumeratedLiteral constructed from CompleteEnumeratedLiteral.

Parameters:
  • bit_bound[in] XTypes v1.3 Clause 7.3.1.2.1.5 It is important to note that the value member of the [bit_bound] annotation may take any value from 1 to 32, inclusive, when this annotation is applied to an enumerated type.

  • bitmask[in] Flag in case that the header being built corresponds to a Bitmask. By default is false.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given bit_bound is not consistent.

Returns:

const CommonEnumeratedHeader instance.

static const CompleteEnumeratedHeader build_complete_enumerated_header(const CommonEnumeratedHeader &common, const CompleteTypeDetail &detail, bool bitmask = false)

Build CompleteEnumeratedHeader instance.

Parameters:
  • common[in] CommonEnumeratedHeader.

  • detail[in] CompleteTypeDetail.

  • bitmask[in] flag set if the given header corresponds to a bitmask. Only required in Debug build mode. Set to false by default.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonEnumeratedHeader is inconsistent (only in Debug build mode).

  2. Given CompleteTypeDetail is inconsistent (only in Debug build mode).

Returns:

const CompleteEnumeratedHeader instance.

static const CompleteEnumeratedType build_complete_enumerated_type(EnumTypeFlag enum_flags, const CompleteEnumeratedHeader &header, const CompleteEnumeratedLiteralSeq &literal_seq)

Build CompleteEnumeratedType instance.

MinimalEnumeratedHeader constructed from CompleteEnumeratedHeader.

Parameters:
  • enum_flags[in] Enumeration flags: unused. No flags apply. It must be 0.

  • header[in] CompleteEnumeratedHeader.

  • literal_seq[in] Sequence of CompleteEnumeratedLiterals.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Any flag is set.

  2. Given CompleteEnumeratedHeader is inconsistent (only in Debug build mode).

  3. Given CompleteEnumeratedLiteralSeq is inconsistent (only in Debug build mode).

Returns:

const CompleteEnumeratedType instance.

static const CommonBitflag build_common_bitflag(uint16_t position, BitflagFlag flags)

Build CommonBitflag instance.

MinimalEnumeratedType constructed from CompleteEnumeratedType.

Parameters:
  • position[in] Bit position in the bitmask.

  • flags[in] Bit flags: unused. No flags apply. It must be 0.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. any given flag is set.

  2. given position is inconsistent. XTypes v1.3 Clause 7.2.2.4.1.2 Each bit in this subset is identified by name and by an index, numbered from 0 to (bound-1). The bound must be greater than zero and no greater than 64.

Returns:

const CommonBitflag instance.

static const CompleteBitflag build_complete_bitflag(const CommonBitflag &common, const CompleteMemberDetail &detail)

Build CompleteBitflag instance.

Parameters:
  • common[in] CommonBitflag.

  • detail[in] CompleteMemberDetail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonBitflag is inconsistent (only in Debug build mode).

  2. Given CompleteMemberDetail is inconsistent (only in Debug build mode).

  3. Non-applicable builtin annotations applied.

Returns:

const CompleteBitflag instance.

static void add_complete_bitflag(CompleteBitflagSeq &sequence, const CompleteBitflag &bitflag)

Add complete bitflag to the sequence.

Parameters:
  • sequence[inout] Sequence to be modified.

  • bitflag[in] CompleteBitflag to be added.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given bitflag is inconsistent (only in Debug build mode).

  2. There is already another bitflag in the sequence with the same position or the same name (only in Debug build mode).

static const CompleteBitmaskType build_complete_bitmask_type(BitmaskTypeFlag bitmask_flags, const CompleteBitmaskHeader &header, const CompleteBitflagSeq &flag_seq)

Build CompleteBitmaskType instance.

MinimalBitflag constructed from CompleteBitflag. CommonBitmaskHeader is not used. CompleteBitmaskHeader is defined as CompleteEnumeratedHeader. MinimalBitmaskHeader is defined as MinimalEnumeratedHeader.

Parameters:
  • bitmask_flags[in] Bitmask flags: unused. No flags apply. It must be 0.

  • header[in] CompleteBitmaskHeader/CompleteEnumeratedHeader

  • flag_seq[in] Sequence of CompleteBitflag.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. any given flag is set.

  2. Given header is inconsistent (only in Debug build mode).

  3. Given Bitflag sequence is inconsistent (only in Debug build mode).

Returns:

const CompleteBitmaskType instance.

static const CommonBitfield build_common_bitfield(uint16_t position, BitsetMemberFlag flags, uint8_t bitcount, TypeKind holder_type)

Build CommonBitfield instance.

Parameters:
  • position[in] Bitfield starting position bit.

  • flags[in] Bitfield flags: unused. No flags apply. It must be 0.

  • bitcount[in] Bitfield number of bits. IDL v4.2 Clause 7.4.13.4.3.2 The first one (positive_int_const) is the number of bits that can be stored (its [bitfield] size). The maximum value is 64.

  • holder_type[in] Type used to manipulate the bitfield. IDL v4.2 Clause 7.4.13.4.3.2 The second optional one (destination_type) specifies the type that will be used to manipulate the bit field as a whole. This type can be boolean, octet or any integer type either signed or unsigned.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given position is not consistent.

  2. Any flag is set.

  3. Given bitcount is not consistent.

  4. Given holder_type is not consistent.

Returns:

const CommonBitfield instance.

static const CompleteBitfield build_complete_bitfield(const CommonBitfield &common, const CompleteMemberDetail &detail)

Build CompleteBitfield instance.

Parameters:
  • common[in] CommonBitfield.

  • detail[in] CompleteMemberDetail.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given CommonBitfield is inconsistent (only Debug build mode).

  2. Give CompleteMemberDetail is inconsistent (only Debug build mode).

  3. Non-applicable builtin annotations are applied.

Returns:

const CompleteBitfield instance.

static void add_complete_bitfield(CompleteBitfieldSeq &sequence, const CompleteBitfield &bitfield)

Add complete bitfield to the sequence.

Parameters:
  • sequence[inout] Sequence to be modified.

  • bitfield[in] CompleteBitfield to be added.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Given bitfield is inconsistent (only in Debug build mode).

  2. There is another bitfield with the same name and/or the same position.

static const CompleteBitsetHeader build_complete_bitset_header(const CompleteTypeDetail &detail)

Build CompleteBitsetHeader instance.

MinimalBitfield constructed from CompleteBitfield.

Parameters:

detail[in] CompleteTypeDetail

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given CompleteTypeDetail is inconsistent (only in Debug build mode).

Returns:

const CompleteBitsetHeader instance.

static const CompleteBitsetType build_complete_bitset_type(BitsetTypeFlag bitset_flags, const CompleteBitsetHeader &header, const CompleteBitfieldSeq &field_seq)

Build CompleteBitsetType instance.

MinimalBitsetHeader constructed from CompleteBitsetHeader.

Parameters:
  • bitset_flags[in] Bitset flags: unused. No flags apply. It must be 0.

  • header[in] CompleteBitsetHeader.

  • field_seq[in] Sequence of complete bitfields.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if:

  1. Any given flag is set.

  2. Given header is inconsistent (only in Debug build mode).

  3. Given bitfield sequence is inconsistent (only in Debug build mode).

Returns:

const CompleteBitsetType instance.

static const CompleteExtendedType build_complete_extended_type()

Build CompleteExtendedType instance. (empty. Available for future extension)

MinimalBitsetType constructed from CompleteBitsetType.

Returns:

const CompleteExtendedType instance.

static ReturnCode_t build_and_register_alias_type_object(const CompleteAliasType &alias_type, const std::string &type_name, TypeIdentifierPair &type_ids)

Register alias TypeObject into TypeObjectRegistry. CompleteAliasType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • alias_type[in] CompleteAliasType.

  • type_name[in] Name to be registered in the registry.

  • type_ids[out] TypeIdentifierPair corresponding to the CompleteAliasType just registered and the generated MinimalAliasType.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_annotation_type_object(const CompleteAnnotationType &annotation_type, const std::string &type_name, TypeIdentifierPair &type_ids)

Register annotation TypeObject into TypeObjectRegistry. CompleteAnnotationType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • annotation_type[in] CompleteAnnotationType.

  • type_name[in] Name to be registered in the registry.

  • type_ids[out] TypeIdentifierPair corresponding to the CompleteAnnotationType just registered and the generated MinimalAnnotationType.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_struct_type_object(const CompleteStructType &struct_type, const std::string &type_name, TypeIdentifierPair &type_ids)

Register structure TypeObject into TypeObjectRegistry. CompleteStructType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • struct_type[in] CompleteStructType.

  • type_name[in] Name to be registered in the registry.

  • type_ids[out] TypeIdentifierPair corresponding to the CompleteStructType just registered and the generated MinimalStructType.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_union_type_object(const CompleteUnionType &union_type, const std::string &type_name, TypeIdentifierPair &type_ids)

Register union TypeObject into TypeObjectRegistry. CompleteUnionType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • union_type[in] CompleteUnionType.

  • type_name[in] Name to be registered in the registry.

  • type_ids[out] TypeIdentifierPair corresponding to the CompleteUnionType just registered and the generated MinimalUnionType.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_bitset_type_object(const CompleteBitsetType &bitset_type, const std::string &type_name, TypeIdentifierPair &type_ids)

Register bitset TypeObject into TypeObjectRegistry. CompleteBitsetType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • bitset_type[in] CompleteBitsetType.

  • type_name[in] Name to be registered in the registry.

  • type_ids[out] TypeIdentifierPair corresponding to the CompleteBitsetType just registered and the generated MinimalBitsetType.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_sequence_type_object(const CompleteSequenceType &sequence_type, const std::string &type_name)

Register sequence TypeObject into TypeObjectRegistry. CompleteSequenceType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • sequence_type[in] CompleteSequenceType.

  • type_name[in] Name to be registered in the registry.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_array_type_object(const CompleteArrayType &array_type, const std::string &type_name)

Register array TypeObject into TypeObjectRegistry. CompleteArrayType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • array_type[in] CompleteArrayType.

  • type_name[in] Name to be registered in the registry.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_map_type_object(const CompleteMapType &map_type, const std::string &type_name)

Register map TypeObject into TypeObjectRegistry. CompleteMapType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • map_type[in] CompleteMapType.

  • type_name[in] Name to be registered in the registry.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_enumerated_type_object(const CompleteEnumeratedType &enumerated_type, const std::string &type_name, TypeIdentifierPair &type_ids)

Register enumeration TypeObject into TypeObjectRegistry. CompleteEnumeratedType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • enumerated_type[in] CompleteEnumeratedType.

  • type_name[in] Name to be registered in the registry.

  • type_ids[out] TypeIdentifierPair corresponding to the CompleteEnumeratedType just registered and the generated MinimalEnumeratedType.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static ReturnCode_t build_and_register_bitmask_type_object(const CompleteBitmaskType &bitmask_type, const std::string &type_name, TypeIdentifierPair &type_ids)

Register bitmask TypeObject into TypeObjectRegistry. CompleteBitmaskType is provided and the minimal TypeObject is constructed from the complete one.

Parameters:
  • bitmask_type[in] CompleteBitmaskType.

  • type_name[in] Name to be registered in the registry.

  • type_ids[out] TypeIdentifierPair corresponding to the CompleteBitmaskType just registered and the generated MinimalBitmaskType.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given type is inconsistent (only in Debug build mode).

Returns:

ReturnCode_t RETCODE_OK if correctly registered in TypeObjectRegistry. RETCODE_BAD_PARAMETER if there is already another different TypeObject registered with the given type_name. RETCODE_BAD_PARAMETER if type_name is empty.

static const NameHash name_hash(const std::string &name)

Calculate the MD5 hash of the provided name.

Parameters:

name[in] String which hash is calculated.

Returns:

const NameHash Hash of the given string.

static void type_object_consistency(const TypeObject &type_object)

Check TypeObject consistency.

Parameters:

type_object[in] Instance to be checked.

Throws:

eprosima::fastdds::dds::xtypes::InvalidArgumentError – exception if the given TypeObject is not consistent.

static const TypeIdentifier &retrieve_minimal_type_identifier(const TypeIdentifierPair &type_ids, bool &ec)

If one of the TypeIdentifier in TypeIdentifierPair is minimal, returns its reference.

Parameters:
  • type_ids[in] TypeIdentifierPair used to retrieve the TypeIdentifier.

  • ec[out] Returns if there was an error.

Returns:

Reference to the minimal TypeIdentifier.

static const TypeIdentifier &retrieve_complete_type_identifier(const TypeIdentifierPair &type_ids, bool &ec)

If one of the TypeIdentifier in TypeIdentifierPair is complete, returns its reference.

Parameters:
  • type_ids[in] TypeIdentifierPair used to retrieve the TypeIdentifier.

  • ec[out] Returns if there was an error.

Returns:

Reference to the complete TypeIdentifier.

20.1.6.4. Utils
ReturnCode_t eprosima::fastdds::dds::idl_serialize(const DynamicType::_ref_type &dynamic_type, std::ostream &output) noexcept

Serializes a DynamicType into its IDL representation.

Parameters:
  • dynamic_type[in] The DynamicType to serialize.

  • output[inout] std::ostream reference containing the IDL representation.

Return values:

RETCODE_OK – when serialization fully succeeds, and inner (member serialization) failing code otherwise.

ReturnCode_t eprosima::fastdds::dds::json_serialize(const DynamicData::_ref_type &data, DynamicDataJsonFormat format, std::ostream &output) noexcept

Serializes a DynamicData into a JSON object, which is then dumped into an std::ostream.

Parameters:
  • data[in] DynamicData reference to be serialized.

  • format[in] DynamicDataJsonFormat JSON serialization format.

  • output[inout] std::ostream reference where the JSON object is dumped.

Return values:

RETCODE_OK – when serialization fully succeeds, and inner (member serialization) failing code otherwise.

20.1.7. RPC over DDS

20.1.7.1. Replier
class Replier : public eprosima::fastdds::dds::rpc::RPCEntity

Base class for a Replier in the RPC communication.

Public Functions

virtual const std::string &get_service_name() const = 0

Returns the name of the service to which the replier belongs.

virtual ReturnCode_t send_reply(void *data, const RequestInfo &info) = 0

Send a reply message.

Parameters:
  • data – Data to send

  • info – Information about the reply sample. This information is used to match the reply with the request through the SampleIdentity

Returns:

RETCODE_OK if the reply was sent successfully or a ReturnCode related to the specific error otherwise

virtual ReturnCode_t take_request(void *data, RequestInfo &info) = 0

Take a request message from the Replier DataReader’s history.

Parameters:
  • data – Data to receive the request

  • info – Information about the request sample

Returns:

RETCODE_OK if the request was taken successfully or a ReturnCode related to the specific error otherwise

virtual ReturnCode_t take_request(LoanableCollection &data, LoanableSequence<RequestInfo> &info) = 0

Take all request messages stored in the Replier DataReader’s history.

Note

This method does not allow to take only the samples associated to a given request. User must implement a zero-copy solution to link request and reply samples.

Parameters:
  • data – Data to receive the request

  • info – Information about the request sample

Returns:

RETCODE_OK if the request was taken successfully or a ReturnCode related to the specific error otherwise

virtual ReturnCode_t return_loan(LoanableCollection &data, LoanableSequence<RequestInfo> &info) = 0

This operation indicates to the Replier’s DataReader that the application is done accessing the collection of Request datas and infos obtained by some earlier invocation of take_request.

Parameters:
  • data[inout] A LoanableCollection object where the received data samples were obtained from an earlier invocation of take_request on this Replier.

  • info[inout] A LoanableSequence where the received request infos were obtained from an earlier invocation of take_request on this Replier.

virtual DataWriter *get_replier_writer() const = 0

Getter for the Replier’s DataWriter.

virtual DataReader *get_replier_reader() const = 0

Getter for the Replier’s DataReader.

20.1.7.2. ReplierQos
class ReplierQos

Public Functions

inline ReplierQos()

Constructor.

inline bool operator==(const ReplierQos &b) const

Equal comparison operator.

Public Members

std::string service_name

Service name.

std::string request_type

Request type.

std::string reply_type

Reply type.

std::string request_topic_name

Request topic name.

std::string reply_topic_name

Reply topic name.

DataWriterQos writer_qos

DataWriter QoS for the reply writer.

DataReaderQos reader_qos

DataReader QoS for the reply reader.

20.1.7.3. Requester
class Requester : public eprosima::fastdds::dds::rpc::RPCEntity

Base class for a Requester in the RPC communication.

Public Functions

virtual const std::string &get_service_name() const = 0

Returns the name of the service to which the requester belongs.

virtual ReturnCode_t send_request(void *data, RequestInfo &info) = 0

Send a request message.

Parameters:
  • data – Data to send

  • info – Information about the request sample. This information is used to match the request with the reply through the SampleIdentity

Returns:

RETCODE_OK if the reply was sent successfully or a ReturnCode related to the specific error otherwise

virtual ReturnCode_t take_reply(void *data, RequestInfo &info) = 0

Take a reply message from the Requester DataReader’s history.

Parameters:
  • data – Data to receive the reply

  • info – Information about the reply sample

Returns:

RETCODE_OK if the reply was taken successfully or a ReturnCode related to the specific error otherwise

virtual ReturnCode_t take_reply(LoanableCollection &data, LoanableSequence<RequestInfo> &info) = 0

Take all reply messages stored in the Requester DataReader’s history.

Note

This method does not allow to take only the samples associated to a given request. User must implement a zero-copy solution to link request and reply samples.

Parameters:
  • data – Data to receive the replies

  • info – Information about the reply samples

Returns:

RETCODE_OK if the replies were taken successfully or a ReturnCode related to the specific error otherwise

virtual ReturnCode_t return_loan(LoanableCollection &data, LoanableSequence<RequestInfo> &info) = 0

This operation indicates to the Requester’s DataReader that the application is done accessing the collection of Reply datas and infos obtained by some earlier invocation of take_reply.

Parameters:
  • data[inout] A LoanableCollection object where the received data samples were obtained from an earlier invocation of take_reply on this Requester.

  • info[inout] A LoanableSequence where the received request infos were obtained from an earlier invocation of take_reply on this Requester.

virtual DataWriter *get_requester_writer() const = 0

Getter for the Requester’s DataWriter.

virtual DataReader *get_requester_reader() const = 0

Getter for the Requester’s DataReader.

20.1.7.4. RequesterQos
class RequesterQos

Public Functions

inline RequesterQos()

Constructor.

inline bool operator==(const RequesterQos &b) const

Equal comparison operator.

Public Members

std::string service_name

Service name.

std::string request_type

Request type.

std::string reply_type

Reply type.

std::string request_topic_name

Request topic name.

std::string reply_topic_name

Reply topic name.

DataWriterQos writer_qos

DataWriter QoS for the request writer.

DataReaderQos reader_qos

DataReader QoS for the request reader.

20.1.7.5. RequestInfo
using eprosima::fastdds::dds::rpc::RequestInfo = SampleInfo
20.1.7.6. RPCEntity
class RPCEntity

Abstract base class for all RPC Objects.

Subclassed by eprosima::fastdds::dds::rpc::Replier, eprosima::fastdds::dds::rpc::Requester, eprosima::fastdds::dds::rpc::Service

Public Functions

virtual ReturnCode_t enable() = 0

Enables the entity.

virtual ReturnCode_t close() = 0

Disables the entity.

virtual bool is_enabled() const = 0

Check if the entity is enabled.

20.1.7.7. Service
class Service : public eprosima::fastdds::dds::rpc::RPCEntity

Base class for a Service in the RPC communication.

Public Functions

virtual const std::string &get_service_name() const = 0

Getter for the service name.

virtual const std::string &get_service_type_name() const = 0

Getter for the service type name.

20.1.7.8. ServiceTypeSupport
class ServiceTypeSupport

Public Functions

ServiceTypeSupport() noexcept = default

Constructor.

ServiceTypeSupport(const ServiceTypeSupport &service_type) noexcept = default

Copy Constructor.

Parameters:

service_type – Another instance of ServiceTypeSupport

ServiceTypeSupport(ServiceTypeSupport &&service_type) noexcept = default

Move Constructor.

Parameters:

service_type – Another instance of ServiceTypeSupport

ServiceTypeSupport &operator=(const ServiceTypeSupport &service_type) noexcept = default

Copy Assignment.

Parameters:

service_type – Another instance of ServiceTypeSupport

ServiceTypeSupport &operator=(ServiceTypeSupport &&service_type) noexcept = default

Move Assignment.

Parameters:

service_type – Another instance of ServiceTypeSupport

inline ServiceTypeSupport(TypeSupport request_type, TypeSupport reply_type)

ServiceTypeSupport constructor that receives two TypeSupport objects (Request + reply TypeSupports)

Parameters:
virtual ~ServiceTypeSupport() = default

Destructor.

virtual ReturnCode_t register_service_type(DomainParticipant *participant, std::string service_type_name) const

Registers the service type on a participant.

Parameters:
  • participantDomainParticipant where the service type is going to be registered

  • service_type_name – Name of the service type to register

Returns:

RETCODE_BAD_PARAMETER if the service name is empty, RETCODE_PRECONDITION_NOT_MET if there is another service with the same name registered on the DomainParticipant and RETCODE_OK if it is registered correctly

inline const TypeSupport request_type() const

Returns the TypeSupport of the request type.

inline const TypeSupport reply_type() const

Returns the TypeSupport of the reply type.

inline bool empty_types() const

Check if the ServiceTypeSupport object contains empty request/reply types.

20.2. RTPS

eProsima Fast DDS Real-Time Publish-Subscribe (RTPS) layer API.

20.2.1. Attributes

20.2.1.1. BuiltinAttributes
class BuiltinAttributes

Class BuiltinAttributes, to define the behavior of the RTPSParticipant builtin protocols.

Public Members

DiscoverySettings discovery_config

Discovery protocol related attributes.

bool use_WriterLivelinessProtocol = true

Indicates to use the WriterLiveliness protocol.

NetworkConfigSet_t network_configuration = 0

Network Configuration.

LocatorList_t metatrafficUnicastLocatorList

Metatraffic Unicast Locator List.

LocatorList_t metatrafficMulticastLocatorList

Metatraffic Multicast Locator List.

fastdds::rtps::ExternalLocators metatraffic_external_unicast_locators

The collection of external locators to use for communication on metatraffic topics.

LocatorList_t initialPeersList

Initial peers.

MemoryManagementPolicy_t readerHistoryMemoryPolicy = MemoryManagementPolicy_t::PREALLOCATED_WITH_REALLOC_MEMORY_MODE

Memory policy for builtin readers.

uint32_t readerPayloadSize = BUILTIN_DATA_MAX_SIZE

Maximum payload size for builtin readers.

MemoryManagementPolicy_t writerHistoryMemoryPolicy = MemoryManagementPolicy_t::PREALLOCATED_WITH_REALLOC_MEMORY_MODE

Memory policy for builtin writers.

uint32_t writerPayloadSize = BUILTIN_DATA_MAX_SIZE

Maximum payload size for builtin writers.

uint32_t mutation_tries = 100u

Mutation tries if the port is being used.

bool avoid_builtin_multicast = true

Set to true to avoid multicast traffic on builtin endpoints.

std::string flow_controller_name = ""

Flow controller name to use for the builtin writers.

20.2.1.2. c_default_RTPSParticipantAllocationAttributes
const RTPSParticipantAllocationAttributes eprosima::fastdds::rtps::c_default_RTPSParticipantAllocationAttributes = RTPSParticipantAllocationAttributes()
20.2.1.3. DiscoveryProtocol
enum class eprosima::fastdds::rtps::DiscoveryProtocol

PDP subclass choice.

Values:

enumerator NONE

NO discovery whatsoever would be used.

Publisher and Subscriber defined with the same topic name would NOT be linked. All matching must be done manually through the addReaderLocator, addReaderProxy, addWriterProxy methods.

enumerator SIMPLE

Discovery works according to ‘The Real-time Publish-Subscribe Protocol(RTPS) DDS Interoperability Wire Protocol Specification’.

enumerator EXTERNAL

A user defined PDP subclass object must be provided in the attributes that deals with the discovery.

Framework is not responsible of this object lifetime.

enumerator CLIENT

The participant will behave as a client concerning discovery operation.

Server locators should be specified as attributes.

enumerator SERVER

The participant will behave as a server concerning discovery operation.

Discovery operation is volatile (discovery handshake must take place if shutdown).

enumerator BACKUP

The participant will behave as a server concerning discovery operation.

Discovery operation persist on a file (discovery handshake wouldn’t repeat if shutdown).

enumerator SUPER_CLIENT

The participant will behave as a client concerning all internal behaviour.

Remote servers will treat it as a server and will share every discovery information.

20.2.1.4. DiscoverySettings
class DiscoverySettings

Class DiscoverySettings, to define the attributes of the several discovery protocols available

Public Functions

inline void static_edp_xml_config(const char *str)

Set the static endpoint XML configuration.

Parameters:

str – URI specifying the static endpoint XML configuration. The string could contain a filename (file://) or the XML content directly (data://).

inline const char *static_edp_xml_config() const

Get the static endpoint XML configuration.

Returns:

URI specifying the static endpoint XML configuration. The string could contain a filename (file://) or the XML content directly (data://).

Public Members

DiscoveryProtocol discoveryProtocol = DiscoveryProtocol::SIMPLE

Chosen discovery protocol.

bool use_SIMPLE_EndpointDiscoveryProtocol = true

If set to true, SimpleEDP would be used.

bool use_STATIC_EndpointDiscoveryProtocol = false

If set to true, StaticEDP based on an XML file would be implemented. The XML filename must be provided.

dds::Duration_t leaseDuration = {20, 0}

Lease Duration of the RTPSParticipant, indicating how much time remote RTPSParticipants should consider this RTPSParticipant alive.

dds::Duration_t leaseDuration_announcementperiod = {3, 0}

The period for the RTPSParticipant to send its Discovery Message to all other discovered RTPSParticipants as well as to all Multicast ports.

InitialAnnouncementConfig initial_announcements

Initial announcements configuration.

SimpleEDPAttributes m_simpleEDP

Attributes of the SimpleEDP protocol.

PDPFactory m_PDPfactory = {}

function that returns a PDP object (only if EXTERNAL selected)

dds::Duration_t discoveryServer_client_syncperiod = {0, 450 * 1000000}

The period for the RTPSParticipant to: send its Discovery Message to its servers check for EDP endpoints matching

eprosima::fastdds::rtps::LocatorList m_DiscoveryServers

Discovery Server initial connections, needed if discoveryProtocol = CLIENT | SUPER_CLIENT | SERVER | BACKUP.

ParticipantFilteringFlags ignoreParticipantFlags = ParticipantFilteringFlags::NO_FILTER

Filtering participants out depending on location.

20.2.1.5. EndpointAttributes
class EndpointAttributes

Structure EndpointAttributes, describing the attributes associated with an RTPS Endpoint.

Public Functions

inline int16_t getUserDefinedID() const

Get the user defined ID

Returns:

User defined ID

inline int16_t getEntityID() const

Get the entity defined ID

Returns:

Entity ID

inline void setUserDefinedID(int16_t id)

Set the user defined ID

Parameters:

id – User defined ID to be set

inline void setEntityID(int16_t id)

Set the entity ID

Parameters:

id – Entity ID to be set

inline void set_data_sharing_configuration(fastdds::dds::DataSharingQosPolicy cfg)

Set the DataSharing configuration

Parameters:

cfg – Configuration to be set

inline const fastdds::dds::DataSharingQosPolicy &data_sharing_configuration() const

Get the DataSharing configuration

Returns:

Configuration of data sharing

Public Members

EndpointKind_t endpointKind = EndpointKind_t::WRITER

Endpoint kind, default value WRITER.

TopicKind_t topicKind = TopicKind_t::NO_KEY

Topic kind, default value NO_KEY.

ReliabilityKind_t reliabilityKind = ReliabilityKind_t::BEST_EFFORT

Reliability kind, default value BEST_EFFORT.

DurabilityKind_t durabilityKind = DurabilityKind_t::VOLATILE

Durability kind, default value VOLATILE.

GUID_t persistence_guid

GUID used for persistence.

ExternalLocators external_unicast_locators

The collection of external locators to use for communication.

bool ignore_non_matching_locators = false

Whether locators that don’t match with the announced locators should be kept.

LocatorList_t unicastLocatorList

Unicast locator list.

LocatorList_t multicastLocatorList

Multicast locator list.

LocatorList_t remoteLocatorList

Remote locator list.

PropertyPolicy properties

Properties.

fastdds::dds::OwnershipQosPolicyKind ownershipKind = fastdds::dds::OwnershipQosPolicyKind::SHARED_OWNERSHIP_QOS

Ownership.

20.2.1.6. ExternalLocators
using eprosima::fastdds::rtps::ExternalLocators = std::map<uint8_t, std::map<uint8_t, std::vector<LocatorWithMask>>, std::greater<uint8_t>>

A collection of LocatorWithMask grouped by externality and cost.

20.2.1.7. HistoryAttributes
class HistoryAttributes

Class HistoryAttributes, to specify the attributes of a WriterHistory or a ReaderHistory. This class is only intended to be used with the RTPS API. The Publisher-Subscriber API has other fields to define this values (HistoryQosPolicy and ResourceLimitsQosPolicy).

Public Functions

inline HistoryAttributes()

Default constructor.

inline HistoryAttributes(MemoryManagementPolicy_t memoryPolicy, uint32_t payload, int32_t initial, int32_t maxRes)

Constructor

Parameters:
  • memoryPolicy – Set whether memory can be dynamically reallocated or not

  • payload – Maximum payload size. It is used when memory management policy is PREALLOCATED_MEMORY_MODE or PREALLOCATED_WITH_REALLOC_MEMORY_MODE.

  • initial – Initial reserved caches. It is used when memory management policy is PREALLOCATED_MEMORY_MODE or PREALLOCATED_WITH_REALLOC_MEMORY_MODE.

  • maxRes – Maximum reserved caches.

inline HistoryAttributes(MemoryManagementPolicy_t memoryPolicy, uint32_t payload, int32_t initial, int32_t maxRes, int32_t extra)

Constructor

Parameters:
  • memoryPolicy – Set whether memory can be dynamically reallocated or not

  • payload – Maximum payload size. It is used when memory management policy is PREALLOCATED_MEMORY_MODE or PREALLOCATED_WITH_REALLOC_MEMORY_MODE.

  • initial – Initial reserved caches. It is used when memory management policy is PREALLOCATED_MEMORY_MODE or PREALLOCATED_WITH_REALLOC_MEMORY_MODE.

  • maxRes – Maximum reserved caches.

  • extra – Extra reserved caches.

Public Members

MemoryManagementPolicy_t memoryPolicy

Memory management policy.

uint32_t payloadMaxSize

Maximum payload size of the history, default value 500.

int32_t initialReservedCaches

Number of the initial Reserved Caches, default value 500.

int32_t maximumReservedCaches

Maximum number of reserved caches. Default value is 0 that indicates to keep reserving until something breaks.

int32_t extraReservedCaches

Number of extra caches that can be reserved for other purposes than the history. For example, on a full history, the writer could give as many as these to be used by the application but they will not be able to be inserted in the history unless some cache from the history is released.

Default value is 1.

20.2.1.8. InitialAnnouncementConfig
struct InitialAnnouncementConfig

Struct InitialAnnouncementConfig defines the behavior of the RTPSParticipant initial announcements.

Public Members

uint32_t count = 5u

Number of initial announcements with specific period (default 5)

dds::Duration_t period = {0, 100000000u}

Specific period for initial announcements (default 100ms)

20.2.1.9. ParticipantFilteringFlags
enum eprosima::fastdds::rtps::ParticipantFilteringFlags

Filtering flags when discovering participants.

Values:

enumerator NO_FILTER
enumerator FILTER_DIFFERENT_HOST
enumerator FILTER_DIFFERENT_PROCESS
enumerator FILTER_SAME_PROCESS
20.2.1.10. PropertyPolicy
class PropertyPolicy

Public Functions

inline const PropertySeq &properties() const

Get properties.

inline PropertySeq &properties()

Set properties.

inline const BinaryPropertySeq &binary_properties() const

Get binary_properties.

inline BinaryPropertySeq &binary_properties()

Set binary_properties.

20.2.1.11. PropertyPolicyHelper
class PropertyPolicyHelper

Public Static Functions

static PropertyPolicy get_properties_with_prefix(const PropertyPolicy &property_policy, const std::string &prefix)

Returns only the properties whose name starts with the prefix.

Prefix is removed in returned properties.

Parameters:
  • property_policyPropertyPolicy where properties will be searched.

  • prefix – Prefix used to search properties.

Returns:

A copy of properties whose name starts with the prefix.

static size_t length(const PropertyPolicy &property_policy)

Get the length of the property_policy.

static std::string *find_property(PropertyPolicy &property_policy, const std::string &name)

Look for a property_policy by name.

static const std::string *find_property(const PropertyPolicy &property_policy, const std::string &name)

Retrieves a property_policy by name.

static const Property *get_property(const PropertyPolicy &property_policy, const std::string &name)

Retrieves a property by name.

Parameters:
  • property_policyPropertyPolicy where the property will be searched.

  • name – Name of the property to be searched.

Returns:

A pointer to the property if found, nullptr otherwise.

20.2.1.12. ReaderAttributes
class ReaderAttributes

Class ReaderAttributes, to define the attributes of a RTPSReader.

Public Members

EndpointAttributes endpoint = {}

Attributes of the associated endpoint.

ReaderTimes times = {}

Times associated with this reader (only for stateful readers)

fastdds::dds::LivelinessQosPolicyKind liveliness_kind = fastdds::dds::LivelinessQosPolicyKind::AUTOMATIC_LIVELINESS_QOS

Liveliness kind.

dds::Duration_t liveliness_lease_duration = {TIME_T_INFINITE_SECONDS, TIME_T_INFINITE_NANOSECONDS}

Liveliness lease duration.

bool expects_inline_qos = false

Indicates if the reader expects Inline qos, default value false.

bool disable_positive_acks = false

Disable positive ACKs.

bool accept_messages_from_unkown_writers = false

Enable or disable the reception of messages from unknown writers.

ResourceLimitedContainerConfig matched_writers_allocation = {}

Define the allocation behaviour for matched-writer-dependent collections.

fastdds::rtps::ThreadSettings data_sharing_listener_thread = {}

Thread settings for the data-sharing listener thread.

20.2.1.13. ReaderTimes
class ReaderTimes

Class ReaderTimes, defining the times associated with the Reliable Readers events.

Public Members

dds::Duration_t initial_acknack_delay = {0, 70 * 1000 * 1000}

Initial AckNack delay. Default value 70ms.

dds::Duration_t heartbeat_response_delay = {0, 5 * 1000 * 1000}

Delay to be applied when a HEARTBEAT message is received, default value 5ms.

20.2.1.14. RemoteLocatorsAllocationAttributes
struct RemoteLocatorsAllocationAttributes

Holds limits for collections of remote locators.

Public Members

size_t max_unicast_locators = 4u

Maximum number of unicast locators per remote entity.

This attribute controls the maximum number of unicast locators to keep for each discovered remote entity (be it a participant, reader of writer). It is recommended to use the highest number of local addresses found on all the systems belonging to the same domain as this participant.

size_t max_multicast_locators = 1u

Maximum number of multicast locators per remote entity.

This attribute controls the maximum number of multicast locators to keep for each discovered remote entity (be it a participant, reader of writer). The default value of 1 is usually enough, as it doesn’t make sense to add more than one multicast locator per entity.

20.2.1.15. RTPSParticipantAllocationAttributes
struct RTPSParticipantAllocationAttributes

Holds allocation limits affecting collections managed by a participant.

Public Functions

inline ResourceLimitedContainerConfig total_readers() const
Returns:

the allocation config for the total of readers in the system (participants * readers)

inline ResourceLimitedContainerConfig total_writers() const
Returns:

the allocation config for the total of writers in the system (participants * writers)

Public Members

RemoteLocatorsAllocationAttributes locators

Holds limits for collections of remote locators.

ResourceLimitedContainerConfig participants

Defines the allocation behaviour for collections dependent on the total number of participants.

ResourceLimitedContainerConfig readers

Defines the allocation behaviour for collections dependent on the total number of readers per participant.

ResourceLimitedContainerConfig writers

Defines the allocation behaviour for collections dependent on the total number of writers per participant.

SendBuffersAllocationAttributes send_buffers

Defines the allocation behaviour for the send buffer manager.

VariableLengthDataLimits data_limits

Holds limits for variable-length data.

fastdds::rtps::ContentFilterProperty::AllocationConfiguration content_filter

Defines the allocation behavior of content filter discovery information.

20.2.1.16. RTPSParticipantAttributes
class RTPSParticipantAttributes

Class RTPSParticipantAttributes used to define different aspects of a RTPSParticipant.

Public Functions

void setup_transports(fastdds::rtps::BuiltinTransports transports, const fastdds::rtps::BuiltinTransportsOptions &options = fastdds::rtps::BuiltinTransportsOptions())

Provides a way of easily configuring transport related configuration on certain pre-defined scenarios with certain options.

Parameters:
  • transports – Defines the transport configuration scenario to setup.

  • options – Defines the options to be used in the transport configuration.

inline void setName(const char *nam)

Set the name of the participant.

inline const char *getName() const

Get the name of the participant.

Public Members

LocatorList_t defaultUnicastLocatorList

Default list of Unicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case that it was defined with NO UnicastLocators. At least ONE locator should be included in this list.

LocatorList_t defaultMulticastLocatorList

Default list of Multicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case that it was defined with NO MulticastLocators. This is usually left empty.

fastdds::rtps::ExternalLocators default_external_unicast_locators

The collection of external locators to use for communication on user created topics.

bool ignore_non_matching_locators = false

Whether locators that don’t match with the announced locators should be kept.

uint32_t sendSocketBufferSize = 0

Send socket buffer size for the send resource.

Zero value indicates to use default system buffer size. Default value: 0.

uint32_t listenSocketBufferSize = 0

Listen socket buffer for all listen resources.

Zero value indicates to use default system buffer size. Default value: 0.

fastdds::rtps::NetmaskFilterKind netmaskFilter = fastdds::rtps::NetmaskFilterKind::AUTO

Netmask filter configuration.

GuidPrefix_t prefix

Optionally allows user to define the GuidPrefix_t.

BuiltinAttributes builtin

Builtin parameters.

PortParameters port

Port Parameters.

std::vector<octet> userData

User Data of the participant.

int32_t participantID = -1

Participant ID.

std::string easy_mode_ip = ""

IP of the Host where master Server is located (EASY_MODE context)

std::vector<std::shared_ptr<fastdds::rtps::TransportDescriptorInterface>> userTransports

User defined transports to use alongside or in place of builtins.

bool useBuiltinTransports = true

Set as false to disable the creation of the default transports.

RTPSParticipantAllocationAttributes allocation

Holds allocation limits affecting collections managed by a participant.

PropertyPolicy properties

Property policies.

FlowControllerDescriptorList flow_controllers

Flow controllers.

fastdds::rtps::ThreadSettings builtin_controllers_sender_thread

Thread settings for the builtin flow controllers sender threads.

fastdds::rtps::ThreadSettings timed_events_thread

Thread settings for the timed events thread.

fastdds::rtps::ThreadSettings discovery_server_thread

Thread settings for the discovery server thread.

fastdds::rtps::ThreadSettings typelookup_service_thread

Thread settings for the builtin TypeLookup service requests and replies threads.

fastdds::rtps::ThreadSettings builtin_transports_reception_threads

Thread settings for the builtin transports reception threads.

fastdds::rtps::ThreadSettings security_log_thread

Thread settings for the security log thread.

uint32_t max_msg_size_no_frag = 0

Maximum message size used to avoid fragmentation, set ONLY in LARGE_DATA.

If this value is not zero, the network factory will allow the initialization of UDP transports with maxMessageSize higher than 65500K.

20.2.1.17. RTPSWriterPublishMode
enum eprosima::fastdds::rtps::RTPSWriterPublishMode

Values:

enumerator SYNCHRONOUS_WRITER
enumerator ASYNCHRONOUS_WRITER
20.2.1.18. SendBuffersAllocationAttributes
struct SendBuffersAllocationAttributes

Holds limits for send buffers allocations.

Public Members

size_t preallocated_number = 0u

Initial number of send buffers to allocate.

This attribute controls the initial number of send buffers to be allocated. The default value of 0 will perform an initial guess of the number of buffers required, based on the number of threads from which a send operation could be started.

bool dynamic = false

Whether the number of send buffers is allowed to grow.

This attribute controls how the buffer manager behaves when a send buffer is not available. When true, a new buffer will be created. When false, it will wait for a buffer to be returned. This is a trade-off between latency and dynamic allocations.

ResourceLimitedContainerConfig network_buffers_config = ResourceLimitedContainerConfig(16u, std::numeric_limits<size_t>::maxdummy_avoid_winmax(), 16u)

Configuration for the network buffers.

This attribute controls the allocation behavior of the network buffers used by each send buffer. The default value will use a value of 16 network buffers for both the preallocated buffers and the dynamic increment allocation, with no maximum limit.

20.2.1.19. SimpleEDPAttributes
class SimpleEDPAttributes

Class SimpleEDPAttributes, to define the attributes of the Simple Endpoint Discovery Protocol.

Public Members

bool use_PublicationWriterANDSubscriptionReader

Default value true.

bool use_PublicationReaderANDSubscriptionWriter

Default value true.

20.2.1.20. ThreadSettings
struct ThreadSettings

Struct ThreadSettings to specify various thread settings. This class is used to define attributes across a wide set of Qos and APIs.

Public Functions

bool operator==(const ThreadSettings &rhs) const

Compare the left hand side (LHS) ThreadSetting with another one for equality.

Parameters:

rhs – The ThreadSettings instance to compare with the LHS one.

bool operator!=(const ThreadSettings &rhs) const

Compare the left hand side (LHS) ThreadSetting with another one for inequality.

Parameters:

rhs – The ThreadSettings instance to compare with the LHS one.

Public Members

int32_t scheduling_policy = -1

The scheduling policy used for this thread.

Configures the scheduling policy used for the thread. A value of -1 indicates system default.

This value is platform specific and it is used as-is to configure the specific platform thread. It is ignored on Windows platforms. Setting this value to something other than the default one may require different privileges on different platforms.

int32_t priority = std::numeric_limits<int32_t>::min()

The thread’s priority.

Configures the thread’s priority. A value of -2^31 indicates system default.

This value is platform specific and it is used as-is to configure the specific platform thread. Setting this value to something other than the default one may require different privileges on different platforms.

uint64_t affinity = 0

The thread’s affinity.

On some systems (Windows, Linux), this is a bit mask for setting the threads affinity to each core individually. On MacOS, this sets the affinity tag for the thread, and the OS tries to share the L2 cache between threads with the same affinity. A value of 0 indicates no particular affinity.

This value is platform specific and it is used as-is to configure the specific platform thread. Setting this value to something other than the default one may require different privileges on different platforms.

int32_t stack_size = -1

The thread’s stack size in bytes.

Configures the thread’s stack size. A value of -1 indicates system default.

This value is platform specific and it is used as-is to configure the specific platform thread. Setting this value to something other than the default one may require different privileges on different platforms.

20.2.1.21. VariableLengthDataLimits
struct VariableLengthDataLimits

Holds limits for variable-length data.

Public Members

size_t max_properties = 0

Defines the maximum size (in octets) of properties data in the local or remote participant.

size_t max_user_data = 0

Defines the maximum size (in octets) of user data in the local or remote participant.

size_t max_partitions = 0

Defines the maximum size (in octets) of partitions data.

size_t max_datasharing_domains = 0

Defines the maximum size (in elements) of the list of data sharing domain IDs.

20.2.1.22. WriterAttributes
class WriterAttributes

Class WriterAttributes, defining the attributes of a RTPSWriter.

Public Members

EndpointAttributes endpoint

Attributes of the associated endpoint.

WriterTimes times

Writer Times (only used for RELIABLE).

fastdds::dds::LivelinessQosPolicyKind liveliness_kind

Liveliness kind.

dds::Duration_t liveliness_lease_duration

Liveliness lease duration.

dds::Duration_t liveliness_announcement_period

Liveliness announcement period.

RTPSWriterPublishMode mode

Indicates if the Writer is synchronous or asynchronous.

bool disable_heartbeat_piggyback

Disable the sending of heartbeat piggybacks.

ResourceLimitedContainerConfig matched_readers_allocation

Define the allocation behaviour for matched-reader-dependent collections.

bool disable_positive_acks

Disable the sending of positive ACKs.

dds::Duration_t keep_duration

Keep duration to keep a sample before considering it has been acked.

std::string flow_controller_name = fastdds::rtps::FASTDDS_FLOW_CONTROLLER_DEFAULT

Flow controller name. Default: fastdds::rtps::FASTDDS_FLOW_CONTROLLER_DEFAULT.

bool separate_sending = false

Whether to send data to each matched reader separately.

20.2.1.23. WriterTimes
struct WriterTimes

Struct WriterTimes, defining the times associated with the Reliable Writers events.

Public Members

dds::Duration_t initial_heartbeat_delay = {0, 12 * 1000 * 1000}

Initial heartbeat delay. Default value 12ms.

dds::Duration_t heartbeat_period = {3, 0}

Periodic HB period, default value 3s.

dds::Duration_t nack_response_delay = {0, 5 * 1000 * 1000}

Delay to apply to the response of a ACKNACK message, default value 5ms.

dds::Duration_t nack_supression_duration = {0, 0}

This time allows the RTPSWriter to ignore nack messages too soon after the data as sent, default value 0s.

20.2.2. Builtin data

20.2.2.1. ContentFilterProperty
class ContentFilterProperty

Information about the content filter being applied by a reader.

Public Functions

inline explicit ContentFilterProperty(const AllocationConfiguration &config)

Construct a ContentFilterProperty.

Parameters:

config – Allocation configuration for the new object.

Public Members

fastcdr::string_255 content_filtered_topic_name

Name of the content filtered topic on which the reader was created.

fastcdr::string_255 related_topic_name

Name of the related topic being filtered.

fastcdr::string_255 filter_class_name

Class name of the filter being used. May be empty to indicate the ContentFilterProperty is not present.

std::string filter_expression

Filter expression indicating which content the reader wants to receive. May be empty to indicate the ContentFilterProperty is not present.

fastdds::ResourceLimitedVector<fastcdr::string_255, std::true_type> expression_parameters

List of values for the parameters present on the filter expression.

struct AllocationConfiguration

Allocation configuration for a ContentFilterProperty.

Public Members

size_t expression_initial_size = 0

Preallocated size of the filter expression.

fastdds::ResourceLimitedContainerConfig expression_parameters = {0, 100, 1}

Allocation configuration for the list of expression parameters.

20.2.2.2. ParticipantBuiltinTopicData
struct ParticipantBuiltinTopicData

Public Functions

ParticipantBuiltinTopicData() = default

Default constructor.

ParticipantBuiltinTopicData(const VendorId_t vendor_id, const dds::DomainId_t domain_id, const RTPSParticipantAllocationAttributes &allocation)

Constructor with allocation attributes.

Public Members

BuiltinTopicKey_t key

Builtin topic Key.

dds::UserDataQosPolicy user_data

UserData QoS.

GUID_t guid

Participant GUID.

dds::ParameterPropertyList_t properties

Properties.

fastcdr::string_255 participant_name

Participant name.

RemoteLocatorList metatraffic_locators

Metatraffic locators.

RemoteLocatorList default_locators

Default locators.

dds::Duration_t lease_duration

Lease Duration.

VendorId_t vendor_id

Vendor id.

ProductVersion_t product_version

Product version.

dds::DomainId_t domain_id

Participant domain id.

fastcdr::optional<dds::WireProtocolConfigQos> wire_protocol

Wire Protocol Qos.

20.2.2.3. PublicationBuiltinTopicData
struct PublicationBuiltinTopicData

Structure PublicationBuiltinTopicData, contains the information on a discovered publication.

Public Members

BuiltinTopicKey_t key = {{0, 0, 0}}

Builtin topic Key.

BuiltinTopicKey_t participant_key = {{0, 0, 0}}

Builtin participant topic Key.

fastcdr::string_255 topic_name

Topic name.

fastcdr::string_255 type_name

Type name.

TopicKind_t topic_kind = TopicKind_t::NO_KEY

Topic kind.

dds::DurabilityQosPolicy durability

Durability Qos, implemented in the library.

dds::DurabilityServiceQosPolicy durability_service

Durability Service Qos, NOT implemented in the library.

dds::DeadlineQosPolicy deadline

Deadline Qos, implemented in the library.

dds::LatencyBudgetQosPolicy latency_budget

Latency Budget Qos, NOT implemented in the library.

dds::LivelinessQosPolicy liveliness

Liveliness Qos, implemented in the library.

dds::ReliabilityQosPolicy reliability

Reliability Qos, implemented in the library.

dds::LifespanQosPolicy lifespan

Lifespan Qos, implemented in the library.

dds::UserDataQosPolicy user_data

User Data Qos, implemented in the library.

dds::OwnershipQosPolicy ownership

Ownership Qos, implemented in the library.

dds::OwnershipStrengthQosPolicy ownership_strength

Ownership Strength Qos, implemented in the library.

dds::DestinationOrderQosPolicy destination_order

Destination Order Qos, NOT implemented in the library.

dds::PresentationQosPolicy presentation

Presentation Qos, NOT implemented in the library.

dds::PartitionQosPolicy partition

Partition Qos, implemented in the library.

dds::TopicDataQosPolicy topic_data

Topic Data Qos, NOT implemented in the library.

dds::GroupDataQosPolicy group_data

Group Data Qos, implemented in the library.

dds::xtypes::TypeInformationParameter type_information

Type information.

dds::DataRepresentationQosPolicy representation

Data representation.

dds::DisablePositiveACKsQosPolicy disable_positive_acks

Disable positive acks, implemented in the library.

dds::DataSharingQosPolicy data_sharing

Information for data sharing compatibility check.

fastcdr::optional<dds::HistoryQosPolicy> history

History Qos, kind and depth.

fastcdr::optional<dds::ResourceLimitsQosPolicy> resource_limits

Resource limits Qos.

fastcdr::optional<dds::TransportPriorityQosPolicy> transport_priority

Transport priority Qos.

fastcdr::optional<dds::WriterDataLifecycleQosPolicy> writer_data_lifecycle

Writer data lifecycle Qos.

fastcdr::optional<dds::PublishModeQosPolicy> publish_mode

Publish mode qos policy.

fastcdr::optional<dds::RTPSReliableWriterQos> rtps_reliable_writer

Reliable writer qos policy.

fastcdr::optional<dds::RTPSEndpointQos> endpoint

Endpoint qos policy.

fastcdr::optional<dds::WriterResourceLimitsQos> writer_resource_limits

Writer resource limits qos policy.

GUID_t guid

GUID.

GUID_t persistence_guid

Persistence GUID.

GUID_t participant_guid

Participant GUID.

RemoteLocatorList remote_locators

Remote locators.

uint32_t max_serialized_size = 0

Maximum serialized size of data type.

NetworkConfigSet_t loopback_transformation = {}

Network configuration.

ParameterPropertyList_t properties

Property list.

20.2.2.4. SubscriptionBuiltinTopicData
struct SubscriptionBuiltinTopicData

Structure SubscriptionBuiltinTopicData, contains the information on a discovered subscription.

Public Members

BuiltinTopicKey_t key = {{0, 0, 0}}

Builtin topic Key.

BuiltinTopicKey_t participant_key = {{0, 0, 0}}

Builtin participant topic Key.

fastcdr::string_255 topic_name

Topic name.

fastcdr::string_255 type_name

Type name.

TopicKind_t topic_kind = TopicKind_t::NO_KEY

Topic kind.

dds::DurabilityQosPolicy durability

Durability Qos, implemented in the library.

dds::DeadlineQosPolicy deadline

Deadline Qos, implemented in the library.

dds::LatencyBudgetQosPolicy latency_budget

Latency Budget Qos, NOT implemented in the library.

dds::LifespanQosPolicy lifespan

Lifespan Qos, implemented in the library.

dds::LivelinessQosPolicy liveliness

Liveliness Qos, implemented in the library.

dds::ReliabilityQosPolicy reliability

Reliability Qos, implemented in the library.

dds::OwnershipQosPolicy ownership

Ownership Qos, implemented in the library.

dds::DestinationOrderQosPolicy destination_order

Destination Order Qos, NOT implemented in the library.

dds::UserDataQosPolicy user_data

User Data Qos, implemented in the library.

dds::TimeBasedFilterQosPolicy time_based_filter

Time Based Filter Qos, NOT implemented in the library.

dds::PresentationQosPolicy presentation

Presentation Qos, NOT implemented in the library.

dds::PartitionQosPolicy partition

Partition Qos, implemented in the library.

dds::TopicDataQosPolicy topic_data

Topic Data Qos, NOT implemented in the library.

dds::GroupDataQosPolicy group_data

Group Data Qos, implemented in the library.

dds::xtypes::TypeInformationParameter type_information

Type information.

dds::DataRepresentationQosPolicy representation

Data representation.

dds::TypeConsistencyEnforcementQosPolicy type_consistency

Type consistency enforcement Qos, NOT implemented in the library.

ContentFilterProperty content_filter = {ContentFilterProperty::AllocationConfiguration{}}

Content filter configuration.

dds::DisablePositiveACKsQosPolicy disable_positive_acks

Disable positive acks, implemented in the library.

dds::DataSharingQosPolicy data_sharing

Information for data sharing compatibility check.

fastcdr::optional<dds::HistoryQosPolicy> history

History Qos, kind and depth.

fastcdr::optional<dds::ResourceLimitsQosPolicy> resource_limits

Resource limits Qos.

fastcdr::optional<dds::ReaderDataLifecycleQosPolicy> reader_data_lifecycle

Reader data lifecycle Qos.

fastcdr::optional<dds::RTPSReliableReaderQos> rtps_reliable_reader

Reliable reader qos policy.

fastcdr::optional<dds::RTPSEndpointQos> endpoint

Endpoint qos policy.

fastcdr::optional<dds::ReaderResourceLimitsQos> reader_resource_limits

Reader resource limits.

GUID_t guid

GUID.

GUID_t participant_guid

Participant GUID.

RemoteLocatorList remote_locators

Remote locators.

NetworkConfigSet_t loopback_transformation = {}

Network configuration.

bool expects_inline_qos = false

Expects Inline Qos.

ParameterPropertyList_t properties

Property list.

20.2.3. Common

20.2.3.1. BinaryProperty
20.2.3.1.1. BinaryProperty
class BinaryProperty
20.2.3.1.2. BinaryPropertyHelper
class BinaryPropertyHelper
20.2.3.1.3. BinaryPropertySeq
typedef std::vector<BinaryProperty> eprosima::fastdds::rtps::BinaryPropertySeq
20.2.3.2. CacheChange
20.2.3.2.1. CacheChange_t
struct CacheChange_t

Structure CacheChange_t, contains information on a specific CacheChange.

Public Functions

inline CacheChange_t()

Default constructor.

Creates an empty CacheChange_t.

inline CacheChange_t(uint32_t payload_size, bool is_untyped = false)

Constructor with payload size

Parameters:
  • payload_size – Serialized payload size

  • is_untyped – Flag to mark the change as untyped.

inline bool copy(const CacheChange_t *ch_ptr)

Copy a different change into this one.

All the elements are copied, included the data, allocating new memory.

Parameters:

ch_ptr[in] Pointer to the change.

Returns:

True if correct.

inline void copy_not_memcpy(const CacheChange_t *ch_ptr)

Copy information form a different change into this one.

All the elements are copied except data.

Parameters:

ch_ptr[in] Pointer to the change.

inline uint32_t getFragmentCount() const

Get the number of fragments this change is split into.

Returns:

number of fragments.

inline uint16_t getFragmentSize() const

Get the size of each fragment this change is split into.

Returns:

size of fragment (0 means change is not fragmented).

inline bool is_fully_assembled()

Checks if all fragments have been received.

Returns:

true when change is fully assembled (i.e. no missing fragments).

inline bool contains_first_fragment()

Checks if the first fragment is present.

Returns:

true when it contains the first fragment. In other case, false.

inline void get_missing_fragments(FragmentNumberSet_t &frag_sns)

Fills a FragmentNumberSet_t with the list of missing fragments.

Parameters:

frag_sns[out] FragmentNumberSet_t where result is stored.

inline void setFragmentSize(uint16_t fragment_size, bool create_fragment_list = false)

Set fragment size for this change.

Remark

Parameter create_fragment_list should only be true when receiving the first fragment of a change.

Parameters:
  • fragment_size – Size of fragments.

  • create_fragment_list – Whether to create missing fragments list or not.

Public Members

ChangeKind_t kind = ALIVE

Kind of change, default value ALIVE.

GUID_t writerGUID = {}

GUID_t of the writer that generated this change.

InstanceHandle_t instanceHandle = {}

Handle of the data associated with this change.

SequenceNumber_t sequenceNumber = {}

SequenceNumber of the change.

SerializedPayload_t serializedPayload = {}

Serialized Payload associated with the change.

SerializedPayload_t inline_qos = {}

CDR serialization of inlined QoS for this change.

bool isRead = false

Indicates if the cache has been read (only used in READERS)

Time_t sourceTimestamp = {}

Source TimeStamp.

fastdds::rtps::VendorId_t vendor_id = c_VendorId_Unknown

Vendor Id of the writer that generated this change.

20.2.3.2.2. ChangeKind_t
enum eprosima::fastdds::rtps::ChangeKind_t

Enumerates the different types of CacheChange_t.

Values:

enumerator ALIVE

ALIVE.

enumerator NOT_ALIVE_DISPOSED

NOT_ALIVE_DISPOSED.

enumerator NOT_ALIVE_UNREGISTERED

NOT_ALIVE_UNREGISTERED.

enumerator NOT_ALIVE_DISPOSED_UNREGISTERED

NOT_ALIVE_DISPOSED_UNREGISTERED.

20.2.3.3. CDRMessage
20.2.3.3.1. CDRMessage_t
struct CDRMessage_t

Structure CDRMessage_t, contains a serialized message.

Public Functions

inline explicit CDRMessage_t(uint32_t size)

Constructor with maximum size

Parameters:

size – Maximum size

inline explicit CDRMessage_t(const SerializedPayload_t &payload)

Constructor to wrap a serialized payload

Parameters:

payload – Payload to wrap

Public Members

octet *buffer

Pointer to the buffer where the data is stored.

uint32_t pos

Read or write position.

uint32_t max_size

Max size of the message.

uint32_t reserved_size

Size allocated on buffer. May be higher than max_size.

uint32_t length

Current length of the message.

Endianness_t msg_endian

Endianness of the message.

20.2.3.3.2. Macro definitions (#define)
RTPSMESSAGE_DEFAULT_SIZE 10500

Max size of RTPS message in bytes.

RTPSMESSAGE_COMMON_RTPS_PAYLOAD_SIZE 536
RTPSMESSAGE_COMMON_DATA_PAYLOAD_SIZE 10000
RTPSMESSAGE_HEADER_SIZE 20
RTPSMESSAGE_SUBMESSAGEHEADER_SIZE 4
RTPSMESSAGE_DATA_EXTRA_INLINEQOS_SIZE 4
RTPSMESSAGE_INFOTS_SIZE 12
RTPSMESSAGE_OCTETSTOINLINEQOS_DATASUBMSG 16
RTPSMESSAGE_OCTETSTOINLINEQOS_DATAFRAGSUBMSG 28
RTPSMESSAGE_DATA_MIN_LENGTH 24
20.2.3.4. CDRSerialization
constexpr eprosima::fastcdr::CdrVersion eprosima::fastdds::rtps::DEFAULT_XCDR_VERSION = {eprosima::fastcdr::CdrVersion::XCDRv1}

Default XCDR encoding version used in Fast DDS.

20.2.3.5. EntityId
20.2.3.5.1. Const values
const EntityId_t eprosima::fastdds::rtps::c_EntityId_Unknown = ENTITYID_UNKNOWN
const EntityId_t eprosima::fastdds::rtps::c_EntityId_SPDPReader = ENTITYID_SPDP_BUILTIN_RTPSParticipant_READER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_SPDPWriter = ENTITYID_SPDP_BUILTIN_RTPSParticipant_WRITER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_SEDPPubWriter = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_SEDPPubReader = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_SEDPSubWriter = ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_SEDPSubReader = ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_RTPSParticipant = ENTITYID_RTPSParticipant
const EntityId_t eprosima::fastdds::rtps::c_EntityId_WriterLiveliness = ENTITYID_P2P_BUILTIN_RTPSParticipant_MESSAGE_WRITER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_ReaderLiveliness = ENTITYID_P2P_BUILTIN_RTPSParticipant_MESSAGE_READER
const EntityId_t eprosima::fastdds::rtps::participant_stateless_message_writer_entity_id = ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_WRITER
const EntityId_t eprosima::fastdds::rtps::participant_stateless_message_reader_entity_id = ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_READER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_TypeLookup_request_writer = ENTITYID_TL_SVC_REQ_WRITER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_TypeLookup_request_reader = ENTITYID_TL_SVC_REQ_READER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_TypeLookup_reply_writer = ENTITYID_TL_SVC_REPLY_WRITER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_TypeLookup_reply_reader = ENTITYID_TL_SVC_REPLY_READER
const EntityId_t eprosima::fastdds::rtps::sedp_builtin_publications_secure_writer = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER
const EntityId_t eprosima::fastdds::rtps::sedp_builtin_publications_secure_reader = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER
const EntityId_t eprosima::fastdds::rtps::sedp_builtin_subscriptions_secure_writer = ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER
const EntityId_t eprosima::fastdds::rtps::sedp_builtin_subscriptions_secure_reader = ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER
const EntityId_t eprosima::fastdds::rtps::participant_volatile_message_secure_writer_entity_id = ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_MESSAGE_SECURE_WRITER
const EntityId_t eprosima::fastdds::rtps::participant_volatile_message_secure_reader_entity_id = ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_MESSAGE_SECURE_READER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_WriterLivelinessSecure = ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER
const EntityId_t eprosima::fastdds::rtps::c_EntityId_ReaderLivelinessSecure = ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER
20.2.3.5.2. Macro definitions (#define)
ENTITYID_UNKNOWN 0x00000000
ENTITYID_RTPSParticipant 0x000001c1
ENTITYID_SEDP_BUILTIN_TOPIC_WRITER 0x000002c2
ENTITYID_SEDP_BUILTIN_TOPIC_READER 0x000002c7
ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER 0x000003c2
ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER 0x000003c7
ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER 0x000004c2
ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER 0x000004c7
ENTITYID_SPDP_BUILTIN_RTPSParticipant_WRITER 0x000100c2
ENTITYID_SPDP_BUILTIN_RTPSParticipant_READER 0x000100c7
ENTITYID_P2P_BUILTIN_RTPSParticipant_MESSAGE_WRITER 0x000200C2
ENTITYID_P2P_BUILTIN_RTPSParticipant_MESSAGE_READER 0x000200C7
ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_WRITER 0x000201C3
ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_READER 0x000201C4
ENTITYID_TL_SVC_REQ_WRITER 0x000300C3
ENTITYID_TL_SVC_REQ_READER 0x000300C4
ENTITYID_TL_SVC_REPLY_WRITER 0x000301C3
ENTITYID_TL_SVC_REPLY_READER 0x000301C4
ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_WRITER 0xff0003c2
ENTITYID_SEDP_BUILTIN_PUBLICATIONS_SECURE_READER 0xff0003c7
ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_WRITER 0xff0004c2
ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_SECURE_READER 0xff0004c7
ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_WRITER 0xff0200c2
ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_SECURE_READER 0xff0200c7
ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_MESSAGE_SECURE_WRITER 0xff0202C3
ENTITYID_P2P_BUILTIN_PARTICIPANT_VOLATILE_MESSAGE_SECURE_READER 0xff0202C4
ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_WRITER 0xff0101c2
ENTITYID_SPDP_RELIABLE_BUILTIN_PARTICIPANT_SECURE_READER 0xff0101c7
20.2.3.5.3. EntityId_t
struct EntityId_t

Structure EntityId_t, entity id part of GUID_t.

Public Functions

inline EntityId_t()

Default constructor. Unknown entity.

inline EntityId_t(uint32_t id)

Main constructor.

Parameters:

id – Entity id

inline EntityId_t(const EntityId_t &id)

Copy constructor.

inline EntityId_t(EntityId_t &&id)

Move constructor.

inline EntityId_t &operator=(uint32_t id)

Assignment operator.

Parameters:

id – Entity id to copy

inline uint32_t to_uint32() const

conversion to uint32_t

Returns:

uint32_t representation

inline bool operator<(const EntityId_t &other) const

Entity Id minor operator

Parameters:

other – Second entity id to compare

Returns:

True if other is higher than this

Public Static Functions

static inline int cmp(const EntityId_t &entity1, const EntityId_t &entity2)

Entity Id compare static method.

Parameters:
  • entity1 – First entity id to compare

  • entity2 – Second entity id to compare

Returns:

0 if entity1 is equal to entity2 .

Returns:

< 0 if entity1 is lower than entity2 .

Returns:

> 0 if entity1 is higher than entity2 .

20.2.3.5.4. EntityId_t Operators
inline bool eprosima::fastdds::rtps::operator==(EntityId_t &id1, const uint32_t id2)

Entity Id comparison operator

Parameters:
  • id1 – EntityId to compare

  • id2 – ID prefix to compare

Returns:

True if equal

inline bool eprosima::fastdds::rtps::operator==(const EntityId_t &id1, const EntityId_t &id2)

Entity Id comparison operator

Parameters:
  • id1 – First EntityId to compare

  • id2 – Second EntityId to compare

Returns:

True if equal

inline bool eprosima::fastdds::rtps::operator!=(const EntityId_t &id1, const EntityId_t &id2)

Guid prefix comparison operator

Parameters:
  • id1 – First EntityId to compare

  • id2 – Second EntityId to compare

Returns:

True if not equal

inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const EntityId_t &enI)
inline std::istream &eprosima::fastdds::rtps::operator>>(std::istream &input, EntityId_t &enP)
20.2.3.6. FragmentNumber
20.2.3.6.1. FragmentNumber_t
using eprosima::fastdds::rtps::FragmentNumber_t = uint32_t
inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const FragmentNumberSet_t &fns)
20.2.3.6.2. FragmentNumberSet_t
using eprosima::fastdds::rtps::FragmentNumberSet_t = BitmapRange<FragmentNumber_t>

Structure FragmentNumberSet_t, contains a group of fragmentnumbers.

20.2.3.7. Guid
20.2.3.7.1. c_Guid_Unknown
const GUID_t eprosima::fastdds::rtps::c_Guid_Unknown
20.2.3.7.2. GUID_t
struct GUID_t

Structure GUID_t, entity identifier, unique in DDS-RTPS Domain.

Public Functions

inline GUID_t() noexcept

Default constructor.

Contructs an unknown GUID.

inline GUID_t(const GuidPrefix_t &guid_prefix, uint32_t id) noexcept

Construct

Parameters:
  • guid_prefix – Guid prefix

  • id – Entity id

inline GUID_t(const GuidPrefix_t &guid_prefix, const EntityId_t &entity_id) noexcept
Parameters:
  • guid_prefix – Guid prefix

  • entity_id – Entity id

inline bool is_on_same_host_as(const GUID_t &other_guid) const

Checks whether this guid is from an entity on the same host as another guid.

Note

This method assumes the value of other_guid was originally assigned by Fast-DDS vendor.

Parameters:

other_guidGUID_t to compare to.

Returns:

true when this guid is on the same host, false otherwise.

inline bool is_from_this_host() const

Checks whether this guid is from a (Fast-DDS) entity created on this host (from where this method is called).

Returns:

true when this guid is from a (Fast-DDS) entity created on this host, false otherwise.

inline bool is_on_same_process_as(const GUID_t &other_guid) const

Checks whether this guid is for an entity on the same host and process as another guid.

Note

This method assumes the value of other_guid was originally assigned by Fast-DDS vendor.

Parameters:

other_guidGUID_t to compare to.

Returns:

true when this guid is on the same host and process, false otherwise.

inline bool is_from_this_process() const

Checks whether this guid is from a (Fast-DDS) entity created on this process (from where this method is called).

Returns:

true when this guid is from a (Fast-DDS) entity created on this process, false otherwise.

inline bool is_builtin() const

Checks whether this guid corresponds to a builtin entity.

Returns:

true when this guid corresponds to a builtin entity, false otherwise.

Public Members

GuidPrefix_t guidPrefix

Guid prefix.

EntityId_t entityId

Entity id.

20.2.3.7.3. GUID_t Operators
inline bool eprosima::fastdds::rtps::operator==(const GUID_t &g1, const GUID_t &g2)

GUID comparison operator

Parameters:
  • g1 – First GUID to compare

  • g2 – Second GUID to compare

Returns:

True if equal

inline bool eprosima::fastdds::rtps::operator!=(const GUID_t &g1, const GUID_t &g2)

GUID comparison operator

Parameters:
  • g1 – First GUID to compare

  • g2 – Second GUID to compare

Returns:

True if not equal

inline bool eprosima::fastdds::rtps::operator<(const GUID_t &g1, const GUID_t &g2)
inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const GUID_t &guid)

Stream operator, prints a GUID.

Parameters:
  • output – Output stream.

  • guidGUID_t to print.

Returns:

Stream operator.

inline std::istream &eprosima::fastdds::rtps::operator>>(std::istream &input, GUID_t &guid)

Stream operator, retrieves a GUID.

Parameters:
  • input – Input stream.

  • guidGUID_t to print.

Returns:

Stream operator.

20.2.3.8. GuidPrefix
20.2.3.8.1. c_GuidPrefix_Unknown
const GuidPrefix_t eprosima::fastdds::rtps::c_GuidPrefix_Unknown
20.2.3.8.2. GuidPrefix_t
struct GuidPrefix_t

Structure GuidPrefix_t, Guid Prefix of GUID_t.

Public Functions

inline GuidPrefix_t()

Default constructor. Set the Guid prefix to 0.

bool is_on_same_host_as(const GuidPrefix_t &other_guid_prefix) const

Checks whether this guid prefix is from an entity on the same host as another guid prefix.

Note

This method assumes the value of other_guid_prefix was originally assigned by Fast-DDS vendor.

Parameters:

other_guid_prefixGuidPrefix_t to compare to.

Returns:

true when this guid prefix is on the same host, false otherwise.

bool is_from_this_host() const

Checks whether this guid prefix is from a (Fast-DDS) entity created on this host (from where this method is called).

Returns:

true when this guid prefix is from a (Fast-DDS) entity created on this host, false otherwise.

bool is_on_same_process_as(const GuidPrefix_t &other_guid_prefix) const

Checks whether this guid prefix is for an entity on the same host and process as another guid prefix.

Note

This method assumes the value of other_guid_prefix was originally assigned by Fast-DDS vendor.

Parameters:

other_guid_prefixGuidPrefix_t to compare to.

Returns:

true when this guid prefix is on the same host and process, false otherwise.

bool is_from_this_process() const

Checks whether this guid prefix is from a (Fast-DDS) entity created on this host and process (from where this method is called).

Returns:

true when this guid prefix is from a (Fast-DDS) entity created on this host and process, false otherwise.

inline bool operator==(const GuidPrefix_t &prefix) const

Guid prefix comparison operator

Parameters:

prefix – guid prefix to compare

Returns:

True if the guid prefixes are equal

inline bool operator!=(const GuidPrefix_t &prefix) const

Guid prefix comparison operator

Parameters:

prefix – Second guid prefix to compare

Returns:

True if the guid prefixes are not equal

inline bool operator<(const GuidPrefix_t &prefix) const

Guid prefix minor operator

Parameters:

prefix – Second guid prefix to compare

Returns:

True if prefix is higher than this

Public Static Functions

static inline int cmp(const GuidPrefix_t &prefix1, const GuidPrefix_t &prefix2)

Guid Prefix compare static method.

Parameters:
  • prefix1 – First guid prefix to compare

  • prefix2 – Second guid prefix to compare

Returns:

0 if prefix1 is equal to prefix2 .

Returns:

< 0 if prefix1 is lower than prefix2 .

Returns:

> 0 if prefix1 is higher than prefix2 .

20.2.3.8.3. GuidPrefix_t Operators
inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const GuidPrefix_t &guiP)
inline std::istream &eprosima::fastdds::rtps::operator>>(std::istream &input, GuidPrefix_t &guiP)
20.2.3.9. InstanceHandle
20.2.3.9.1. c_InstanceHandle_Unknown
const InstanceHandle_t eprosima::fastdds::rtps::c_InstanceHandle_Unknown
20.2.3.9.2. InstanceHandle_t
struct InstanceHandle_t

Struct InstanceHandle_t, used to contain the key for WITH_KEY topics.

Public Functions

InstanceHandle_t &operator=(const InstanceHandle_t &ihandle) noexcept = default

Assignment operator

Parameters:

ihandle – Instance handle to copy the data from

inline InstanceHandle_t &operator=(const GUID_t &guid) noexcept

Assignment operator

Parameters:

guid – GUID to copy the data from

inline bool isDefined() const noexcept

Know if the instance handle is defined

Returns:

True if the values are not zero.

Public Members

InstanceHandleValue_t value

Value.

20.2.3.9.3. InstanceHandle_t Operators
inline bool eprosima::fastdds::rtps::operator==(const InstanceHandle_t &ihandle1, const InstanceHandle_t &ihandle2) noexcept

Comparison operator

Parameters:
Returns:

True if equal

inline bool eprosima::fastdds::rtps::operator!=(const InstanceHandle_t &ihandle1, const InstanceHandle_t &ihandle2) noexcept

Comparison operator.

Parameters:
Returns:

True if not equal

inline bool eprosima::fastdds::rtps::operator<(const InstanceHandle_t &h1, const InstanceHandle_t &h2) noexcept

Comparison operator: checks if a InstanceHandle_t is less than another.

Parameters:
Returns:

True if the first InstanceHandle_t is less than the second.

inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const InstanceHandle_t &iHandle)

Stream operator: print an InstanceHandle_t.

Parameters:
Returns:

Stream operator.

inline std::istream &eprosima::fastdds::rtps::operator>>(std::istream &input, InstanceHandle_t &iHandle)

Stream operator: retrieve an InstanceHandle_t.

Parameters:
  • input – Input stream.

  • iHandleInstanceHandle_t that will receive the input as its new value.

Returns:

Stream operator.

inline void eprosima::fastdds::rtps::iHandle2GUID(GUID_t &guid, const InstanceHandle_t &ihandle) noexcept

Convert InstanceHandle_t to GUID

Parameters:
inline GUID_t eprosima::fastdds::rtps::iHandle2GUID(const InstanceHandle_t &ihandle) noexcept

Convert GUID to InstanceHandle_t

Parameters:

ihandleInstanceHandle_t to store the results

Returns:

GUID_t

20.2.3.10. Locator
20.2.3.10.1. Macro definitions (#define)
LOCATOR_INVALID(loc)                                {loc.kind = LOCATOR_KIND_INVALID; loc.port = LOCATOR_PORT_INVALID; \                                LOCATOR_ADDRESS_INVALID

(loc.address); \

}


Initialize locator with invalid values.

LOCATOR_KIND_INVALID -1

Invalid locator kind.

LOCATOR_ADDRESS_INVALID(a) {std::memset(a, 0x00, 16 * sizeof(octet));}

Set locator IP address to 0.

LOCATOR_PORT_INVALID 0

Invalid locator port.

LOCATOR_KIND_RESERVED 0

Reserved locator kind.

LOCATOR_KIND_UDPv4 1

UDP over IPv4 locator kind.

LOCATOR_KIND_UDPv6 2

UDP over IPv6 locator kind.

LOCATOR_KIND_TCPv4 4

TCP over IPv4 kind.

LOCATOR_KIND_TCPv6 8

TCP over IPv6 locator kind.

LOCATOR_KIND_SHM 16 + FASTDDS_VERSION_MAJOR

Shared memory locator kind.

20.2.3.10.2. IsAddressDefined
inline bool eprosima::fastdds::rtps::IsAddressDefined(const Locator_t &loc)

Auxiliary method to check that IP address is not invalid (0).

Parameters:

loc – Locator which IP address is going to be checked.

Returns:

true if IP address is defined (not 0).

Returns:

false otherwise.

20.2.3.10.3. IsLocatorValid
inline bool eprosima::fastdds::rtps::IsLocatorValid(const Locator_t &loc)

Auxiliary method to check that locator kind is not LOCATOR_KIND_INVALID (-1).

Parameters:

loc – Locator to be checked.

Returns:

true if the locator kind is not LOCATOR_KIND_INVALID.

Returns:

false otherwise.

20.2.3.10.4. Locator_t
class Locator_t

Class Locator_t, uniquely identifies a communication channel for a particular transport. For example, an address + port combination in the case of UDP.

Subclassed by eprosima::fastdds::rtps::LocatorWithMask

Public Functions

inline Locator_t()

Default constructor.

inline Locator_t(Locator_t &&loc)

Move constructor.

inline Locator_t(const Locator_t &loc)

Copy constructor.

inline Locator_t(uint32_t portin)

Port constructor.

inline Locator_t(int32_t kindin, uint32_t portin)

Kind and port constructor.

inline Locator_t &operator=(const Locator_t &loc)

Copy assignment.

inline bool set_address(const Locator_t &other)

Set the locator IP address using another locator.

Parameters:

other – Locator which IP address is used to set this locator IP address.

Returns:

always true.

inline octet *get_address()

Getter for the locator IP address.

Returns:

IP address as octet pointer.

inline octet get_address(uint16_t field) const

Getter for a specific field of the locator IP address.

Parameters:

field – IP address element to be accessed.

Returns:

Octet value for the specific IP address element.

inline void set_Invalid_Address()

Automatic setter for setting locator IP address to invalid address (0).

Public Members

int32_t kind

Specifies the locator type. Valid values are:

LOCATOR_KIND_UDPv4

LOCATOR_KIND_UDPv6

LOCATOR_KIND_TCPv4

LOCATOR_KIND_TCPv6

LOCATOR_KIND_SHM

uint32_t port

Network port.

octet address[16]

IP address.

20.2.3.10.5. LocatorList
class LocatorList

Class LocatorList, a Locator vector that doesn’t allow duplicates.

Public Functions

inline LocatorList()

Constructor.

inline ~LocatorList()

Destructor.

inline LocatorList(const LocatorList &list)

Copy constructor.

inline LocatorList(LocatorList &&list)

Move constructor.

inline LocatorList &operator=(const LocatorList &list)

Copy assignment.

inline LocatorList &operator=(LocatorList &&list)

Move assignment.

inline bool operator==(const LocatorList &locator_list) const

Equal to operator.

inline bool operator!=(const LocatorList &locator_list) const

Not equal to operator.

inline LocatorListIterator begin()

Return an iterator to the beginning.

Returns:

LocatorListIterator iterator to the first locator.

inline LocatorListIterator end()

Return an iterator to the end.

Returns:

LocatorListIterator iterator to the element following the last element.

inline LocatorListConstIterator begin() const

Return a constant iterator to the beginning.

Returns:

LocatorListConstIterator iterator to the first locator.

inline LocatorListConstIterator end() const

Return a constant iterator to the end.

Returns:

LocatorListConstIterator iterator to the element following the last element.

inline size_t size() const

Return the number of locators.

Returns:

size_t The number of locators in the container.

inline LocatorList &assign(const LocatorList &list)

Replace the contents of the container.

Parameters:

list – New content to be saved into the container.

Returns:

LocatorList& reference to the container with the replaced content.

inline void clear()

Erase all locators from the container.

inline void reserve(size_t num)

Reserve storage increasing the capacity of the vector.

Parameters:

num – new capacity of the vector, in number of elements.

inline void resize(size_t num)

Resize the container to contain num locators. If the current size is greater than num, the container is reduced to its first num locators. If the current size is less than count, additional default-inserted locators are appended.

Parameters:

num – new size of the container.

inline void push_back(const Locator &loc)

Add locator to the end if not found within the list.

Parameters:

loc – locator to be appended.

inline void push_back(const LocatorList &locList)

Add several locators to the end if not already present within the list.

Parameters:

locListLocatorList with the locators to be appended.

inline bool empty() const

Check that the container has no locators.

Returns:

true if the container is empty. False otherwise.

inline void erase(const Locator &loc)

Erase the specified locator from the container.

Parameters:

loc – Locator to be removed.

inline bool isValid() const

Check that every locator contained in the list is not LOCATOR_KIND_INVALID.

Returns:

true if all locators are valid. False otherwise.

inline void swap(LocatorList &locatorList)

exchange the content of the container.

Parameters:

locatorList – container to exchange the contents with.

20.2.3.10.6. LocatorListConstIterator
typedef std::vector<Locator_t>::const_iterator eprosima::fastdds::rtps::LocatorListConstIterator

Constant iterator to iterate over a vector of locators.

20.2.3.10.7. LocatorListIterator
typedef std::vector<Locator_t>::iterator eprosima::fastdds::rtps::LocatorListIterator

Iterator to iterate over a vector of locators.

20.2.3.10.8. LocatorsIterator
struct LocatorsIterator

Provides a Locator’s iterator interface that can be used by different Locator’s containers

Subclassed by eprosima::fastdds::rtps::Locators, eprosima::fastdds::rtps::LocatorSelector::iterator

Public Functions

virtual LocatorsIterator &operator++() = 0

Increment operator.

Returns:

LocatorsIterator& reference to the next LocatorsIterator.

virtual bool operator==(const LocatorsIterator &other) const = 0

Equal to operator.

Parameters:

otherLocatorsIterator to compare.

Returns:

true if equal.

Returns:

false otherwise.

virtual bool operator!=(const LocatorsIterator &other) const = 0

Not equal to operator.

Parameters:

otherLocatorsIterator to compare.

Returns:

true if not equal.

Returns:

false otherwise.

virtual const Locator &operator*() const = 0

Dereference operator.

Returns:

const Locator& Reference to the locator pointed by the LocatorsIterator.

20.2.3.10.9. Locators
class Locators : public eprosima::fastdds::rtps::LocatorsIterator

Adapter class that provides a LocatorsIterator interface from a LocatorListConstIterator

Public Functions

inline Locators(const LocatorListConstIterator &it)

Constructor.

inline Locators(const Locators &other)

Copy constructor.

inline virtual LocatorsIterator &operator++()

Increment operator.

Returns:

LocatorsIterator& reference to the next LocatorsIterator.

inline virtual bool operator==(const LocatorsIterator &other) const

Equal to operator.

Parameters:

otherLocatorsIterator to compare.

Returns:

true if equal.

Returns:

false otherwise.

inline virtual bool operator!=(const LocatorsIterator &other) const

Not equal to operator.

Parameters:

otherLocatorsIterator to compare.

Returns:

true if not equal.

Returns:

false otherwise.

inline virtual const Locator &operator*() const

Dereference operator.

Returns:

const Locator& Reference to the locator pointed by the LocatorsIterator.

20.2.3.10.10. Locator Operators
inline bool eprosima::fastdds::rtps::operator<(const Locator_t &loc1, const Locator_t &loc2)

Less than operator.

Parameters:
  • loc1 – Left hand side locator being compared.

  • loc2 – Right hand side locator being compared.

Returns:

true if loc1 is less than loc2.

Returns:

false otherwise.

inline bool eprosima::fastdds::rtps::operator==(const Locator_t &loc1, const Locator_t &loc2)

Equal to operator.

Parameters:
  • loc1 – Left hand side locator being compared.

  • loc2 – Right hand side locator being compared.

Returns:

true if loc1 is equal to loc2.

Returns:

false otherwise.

inline bool eprosima::fastdds::rtps::operator!=(const Locator_t &loc1, const Locator_t &loc2)

Not equal to operator.

Parameters:
  • loc1 – Left hand side locator being compared.

  • loc2 – Right hand side locator being compared.

Returns:

true if loc1 is not equal to loc2.

Returns:

false otherwise.

inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const Locator_t &loc)

Insertion operator: serialize a locator The serialization format is kind:[address]:port kind must be one of the following:

  • UDPv4

  • UDPv6

  • TCPv4

  • TCPv6

  • SHM address IP address unless kind is SHM port number

Parameters:
  • output – Output stream where the serialized locator is appended.

  • loc – Locator to be serialized/inserted.

Returns:

std::ostream& Reference to the output stream with the serialized locator appended.

inline std::istream &eprosima::fastdds::rtps::operator>>(std::istream &input, Locator_t &loc)

Extraction operator: deserialize a locator The deserialization format is kind:[address]:port kind must be one of the following:

  • UDPv4

  • UDPv6

  • TCPv4

  • TCPv6

  • SHM address must be either a name which can be resolved by DNS or the IP address unless kind is SHM port number

Parameters:
  • input – Input stream where the locator to be deserialized is located.

  • loc – Locator where the deserialized locator is saved.

Returns:

std::istream& Reference to the input stream after extracting the locator.

inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const LocatorList &locList)

Insertion operator: serialize a locator list. The deserialization format is [locator1,locator2,…,locatorN]. Each individual locator within the list must follow the serialization format explained in the locator insertion operator.

Parameters:
  • output – Output stream where the serialized locator list is appended.

  • locList – Locator list to be serialized/inserted.

Returns:

std::ostream& Reference to the output stream with the serialized locator list appended.

inline std::istream &eprosima::fastdds::rtps::operator>>(std::istream &input, LocatorList &locList)

Extraction operator: deserialize a list of locators. The serialization format is [locator1,locator2,…,locatorN]. Each individual locator within the list must follow the deserialization format explained in the locator extraction operator.

Parameters:
  • input – Input stream where the locator list to be deserialized is located.

  • locList – Locator list where the deserialized locators are saved.

Returns:

std::istream& Reference to the input stream after extracting the locator list.

static inline bool eprosima::fastdds::rtps::operator==(const ResourceLimitedVector<Locator_t> &lhs, const ResourceLimitedVector<Locator_t> &rhs)

Equal to operator to compare two locator lists.

Parameters:
  • lhs – Locator list to be compared.

  • rhs – Other locator list to be compared.

Returns:

true if the list are equal.

Returns:

false otherwise.

20.2.3.11. LocatorSelectorEntry
struct LocatorSelectorEntry

An entry for the LocatorSelector.

This class holds the locators of a remote endpoint along with data required for the locator selection algorithm.

Public Functions

inline LocatorSelectorEntry(size_t max_unicast_locators, size_t max_multicast_locators)

Construct a LocatorSelectorEntry.

Parameters:
  • max_unicast_locators – Maximum number of unicast locators to hold.

  • max_multicast_locators – Maximum number of multicast locators to hold.

inline void enable(bool should_enable)

Set the enabled value.

Parameters:

should_enable – Whether this entry should be enabled.

inline void reset()

Reset the selections.

Public Members

GUID_t remote_guid

GUID of the remote entity.

ResourceLimitedVector<Locator_t> unicast

List of unicast locators to send data to the remote entity.

ResourceLimitedVector<Locator_t> multicast

List of multicast locators to send data to the remote entity.

EntryState state

State of the entry.

bool enabled

Indicates whether this entry should be taken into consideration.

bool transport_should_process

A temporary value for each transport to help optimizing some use cases.

struct EntryState

Holds the selection state of the locators held by a LocatorSelectorEntry

Public Functions

inline EntryState(size_t max_unicast_locators, size_t max_multicast_locators)

Construct an EntryState object.

Parameters:
  • max_unicast_locators – Maximum number of unicast locators to held by parent LocatorSelectorEntry.

  • max_multicast_locators – Maximum number of multicast locators to held by parent LocatorSelectorEntry.

Public Members

ResourceLimitedVector<size_t> unicast

Unicast locators selection state.

ResourceLimitedVector<size_t> multicast

Multicast locators selection state.

20.2.3.12. LocatorSelector
class LocatorSelector

A class used for the efficient selection of locators when sending data to multiple entities.

Algorithm:

  • Entries are added/removed with add_entry/remove_entry when matched/unmatched.

  • When data is to be sent:

    • A reference to this object is passed to the message group

    • For each submessage:

      • A call to reset is performed

      • A call to enable is performed per desired destination

      • If state_has_changed() returns true:

        • the message group is flushed

        • selection_start is called

        • for each transport:

          • transport_starts is called

          • transport handles the selection state of each entry

          • select may be called

      • Submessage is added to the message group

Public Functions

inline LocatorSelector(const ResourceLimitedContainerConfig &entries_allocation)

Construct a LocatorSelector.

Parameters:

entries_allocation – Allocation configuration regarding the number of remote entities.

inline void clear()

Clears all internal data.

inline bool add_entry(LocatorSelectorEntry *entry)

Add an entry to this selector.

Parameters:

entry – Pointer to the LocatorSelectorEntry to add.

inline bool remove_entry(const GUID_t &guid)

Remove an entry from this selector.

Parameters:

guid – Identifier of the entry to be removed.

inline void reset(bool enable_all)

Reset the enabling state of the selector.

Parameters:

enable_all – Indicates whether entries should be initially enabled.

inline void enable(const GUID_t &guid)

Enable an entry given its GUID.

Parameters:

guid – GUID of the entry to enable.

inline bool state_has_changed() const

Check if enabling state has changed.

Returns:

true if the enabling state has changed, false otherwise.

inline void selection_start()

Reset the selection state of the selector.

inline ResourceLimitedVector<LocatorSelectorEntry*> &transport_starts()

Called when the selection algorithm starts for a specific transport.

Will set the temporary transport_should_process flag for all enabled entries.

Returns:

a reference to the entries collection.

inline void select(size_t index)

Marks an entry as selected.

Parameters:

index – The index of the entry to mark as selected.

inline size_t selected_size() const

Count the number of selected locators.

Returns:

the number of selected locators.

inline bool is_selected(const Locator_t locator) const

Check if a locator is present in the selections of this object.

Parameters:

locator – The locator to be checked.

Returns:

True if the locator has been selected, false otherwise.

template<class UnaryPredicate>
inline void for_each(UnaryPredicate action) const

Performs an action on each selected locator.

Parameters:

action – Unary function that accepts a locator as argument. The function shall not modify its argument. This can either be a function pointer or a function object.

class iterator : public eprosima::fastdds::rtps::LocatorsIterator

Public Functions

inline virtual iterator &operator++()

Increment operator.

Returns:

LocatorsIterator& reference to the next LocatorsIterator.

inline virtual bool operator==(const LocatorsIterator &other) const

Equal to operator.

Parameters:

otherLocatorsIterator to compare.

Returns:

true if equal.

Returns:

false otherwise.

inline virtual bool operator!=(const LocatorsIterator &other) const

Not equal to operator.

Parameters:

otherLocatorsIterator to compare.

Returns:

true if not equal.

Returns:

false otherwise.

inline virtual reference operator*() const

Dereference operator.

Returns:

const Locator& Reference to the locator pointed by the LocatorsIterator.

struct IteratorIndex
20.2.3.13. LocatorWithMask
class LocatorWithMask : public eprosima::fastdds::rtps::Locator_t

A Locator with a mask that defines the number of significant bits of its address.

Public Functions

uint8_t mask() const

Get the number of significant bits on the address of this locator.

Returns:

number of significant bits on the address of this locator.

void mask(uint8_t mask)

Set the number of significant bits on the address of this locator.

Parameters:

mask – number of significant bits on the address of this locator.

bool matches(const Locator &loc) const

Check whether the given locator is from the same network as this locator.

Parameters:

loc – locator to check if belonging to the same network as this locator.

Returns:

true if the two locators are from the same network, false otherwise.

LocatorWithMask &operator=(const Locator &loc)

Copy assignment.

20.2.3.14. MatchingInfo
20.2.3.14.1. MatchingInfo
class MatchingInfo

Class MatchingInfo contains information about the matching between two endpoints.

Public Functions

inline MatchingInfo()

Default constructor.

inline MatchingInfo(MatchingStatus stat, const GUID_t &guid)
Parameters:
  • stat – Status

  • guid – GUID

Public Members

MatchingStatus status

Status.

GUID_t remoteEndpointGuid

Remote endpoint GUID.

20.2.3.14.2. MatchingStatus
enum eprosima::fastdds::rtps::MatchingStatus

Indicates whether the matched publication/subscription method of the PublisherListener or SubscriberListener has been called for a matching or a removal of a remote endpoint.

Values:

enumerator MATCHED_MATCHING

MATCHED_MATCHING, new publisher/subscriber found.

enumerator REMOVED_MATCHING

REMOVED_MATCHING, publisher/subscriber removed.

20.2.3.15. PortParameters
class PortParameters

Class PortParameters, to define the port parameters and gains related with the RTPS protocol.

Public Functions

inline uint32_t getMulticastPort(uint32_t domainId) const

Get a multicast port based on the domain ID.

Parameters:

domainId – Domain ID.

Returns:

Multicast port

inline uint32_t getUnicastPort(uint32_t domainId, uint32_t RTPSParticipantID) const

Get a unicast port based on the domain ID and the participant ID.

Parameters:
  • domainId – Domain ID.

  • RTPSParticipantID – Participant ID.

Returns:

Unicast port

inline uint16_t get_discovery_server_port(uint32_t domainId) const

Get a discovery server port based on the domain ID.

Parameters:

domainId – Domain ID.

Returns:

Discovery server port

Public Members

uint16_t portBase

PortBase, default value 7400.

uint16_t domainIDGain

DomainID gain, default value 250.

uint16_t participantIDGain

ParticipantID gain, default value 2.

uint16_t offsetd0

Offset d0, default value 0.

uint16_t offsetd1

Offset d1, default value 10.

uint16_t offsetd2

Offset d2, default value 1.

uint16_t offsetd3

Offset d3, default value 11.

uint16_t offsetd4

Offset d4, default value 2.

20.2.3.16. Property
20.2.3.16.1. Property
class Property
20.2.3.16.2. PropertyHelper
class PropertyHelper
20.2.3.16.3. PropertySeq
typedef std::vector<Property> eprosima::fastdds::rtps::PropertySeq
20.2.3.17. RemoteLocators
20.2.3.17.1. RemoteLocators Operators
inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const RemoteLocatorList &remote_locators)
20.2.3.17.2. RemoteLocatorList
struct RemoteLocatorList

Holds information about the locators of a remote entity.

Public Functions

inline RemoteLocatorList()

Default constructor of RemoteLocatorList for deserialize.

inline RemoteLocatorList(size_t max_unicast_locators, size_t max_multicast_locators)

Construct a RemoteLocatorList.

Parameters:
  • max_unicast_locators – Maximum number of unicast locators to hold.

  • max_multicast_locators – Maximum number of multicast locators to hold.

inline RemoteLocatorList(const RemoteLocatorList &other)

Copy-construct a RemoteLocatorList.

Parameters:

otherRemoteLocatorList to copy data from.

inline RemoteLocatorList &operator=(const RemoteLocatorList &other)

Assign locator values from other RemoteLocatorList.

Remark

Using the assignment operator is different from copy-constructing as in the first case the configuration with the maximum number of locators is not copied. This means that, for two lists with different maximum number of locators, the expression (a = b) == b may not be true.

Parameters:

otherRemoteLocatorList to copy data from.

inline void add_unicast_locator(const Locator_t &locator)

Adds a locator to the unicast list.

If the locator already exists in the unicast list, or the maximum number of unicast locators has been reached, the new locator is silently discarded.

Parameters:

locator – Unicast locator to be added.

inline void add_multicast_locator(const Locator_t &locator)

Adds a locator to the multicast list.

If the locator already exists in the multicast list, or the maximum number of multicast locators has been reached, the new locator is silently discarded.

Parameters:

locator – Multicast locator to be added.

Public Members

ResourceLimitedVector<Locator_t> unicast

List of unicast locators.

ResourceLimitedVector<Locator_t> multicast

List of multicast locators.

20.2.3.18. SampleIdentity
class SampleIdentity

This class is used to specify a sample.

Public Functions

inline SampleIdentity()

Default constructor.

Constructs an unknown SampleIdentity.

inline SampleIdentity(const SampleIdentity &sample_id)

Copy constructor.

inline SampleIdentity(SampleIdentity &&sample_id)

Move constructor.

inline SampleIdentity &operator=(const SampleIdentity &sample_id)

Assignment operator.

inline SampleIdentity &operator=(SampleIdentity &&sample_id)

Move constructor.

inline bool operator<(const SampleIdentity &sample) const

To allow using SampleIdentity as map key.

Parameters:

sample

Returns:

20.2.3.19. SequenceNumber
20.2.3.19.1. c_SequenceNumber_Unknown
const SequenceNumber_t eprosima::fastdds::rtps::c_SequenceNumber_Unknown = {-1, 0}
20.2.3.19.2. SequenceNumber_t Operators
inline bool eprosima::fastdds::rtps::operator==(const SequenceNumber_t &sn1, const SequenceNumber_t &sn2) noexcept

Compares two SequenceNumber_t.

Parameters:
Returns:

True if equal

inline bool eprosima::fastdds::rtps::operator!=(const SequenceNumber_t &sn1, const SequenceNumber_t &sn2) noexcept

Compares two SequenceNumber_t.

Parameters:
Returns:

True if not equal

inline bool eprosima::fastdds::rtps::operator>(const SequenceNumber_t &seq1, const SequenceNumber_t &seq2) noexcept

Checks if a SequenceNumber_t is greater than other.

Parameters:
Returns:

True if the first SequenceNumber_t is greater than the second

inline bool eprosima::fastdds::rtps::operator<(const SequenceNumber_t &seq1, const SequenceNumber_t &seq2) noexcept

Checks if a SequenceNumber_t is less than other.

Parameters:
Returns:

True if the first SequenceNumber_t is less than the second

inline bool eprosima::fastdds::rtps::operator>=(const SequenceNumber_t &seq1, const SequenceNumber_t &seq2) noexcept

Checks if a SequenceNumber_t is greater or equal than other.

Parameters:
Returns:

True if the first SequenceNumber_t is greater or equal than the second

inline bool eprosima::fastdds::rtps::operator<=(const SequenceNumber_t &seq1, const SequenceNumber_t &seq2) noexcept

Checks if a SequenceNumber_t is less or equal than other.

Parameters:
Returns:

True if the first SequenceNumber_t is less or equal than the second

inline SequenceNumber_t eprosima::fastdds::rtps::operator-(const SequenceNumber_t &seq, const uint32_t inc) noexcept

Subtract one uint32_t from a SequenceNumber_t

Parameters:
Returns:

Result of the subtraction

inline SequenceNumber_t eprosima::fastdds::rtps::operator+(const SequenceNumber_t &seq, const uint32_t inc) noexcept

Add one uint32_t to a SequenceNumber_t

Parameters:
  • seq[in] Base sequence number

  • inc – value to add to the base

Returns:

Result of the addition

inline SequenceNumber_t eprosima::fastdds::rtps::operator-(const SequenceNumber_t &minuend, const SequenceNumber_t &subtrahend) noexcept

Subtract one SequenceNumber_t to another

Parameters:
  • minuend – Minuend. Has to be greater than or equal to subtrahend.

  • subtrahend – Subtrahend.

Returns:

Result of the subtraction

inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const SequenceNumber_t &seqNum)
Parameters:
  • output

  • seqNum

Returns:

inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const std::vector<SequenceNumber_t> &seqNumSet)
inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const SequenceNumberSet_t &sns)

Prints a sequence Number set

Parameters:
  • output – Output Stream

  • sns – SequenceNumber set

Returns:

OStream.

20.2.3.19.3. SequenceNumber_t
struct SequenceNumber_t

Structure SequenceNumber_t, different for each change in the same writer.

Public Functions

inline SequenceNumber_t() noexcept

Default constructor.

inline SequenceNumber_t(int32_t hi, uint32_t lo) noexcept
Parameters:
  • hi

  • lo

inline explicit SequenceNumber_t(uint64_t u) noexcept
Parameters:

u

inline uint64_t to64long() const noexcept

Convert the number to 64 bit.

Returns:

64 bit representation of the SequenceNumber

inline SequenceNumber_t &operator++() noexcept

Increase SequenceNumber in 1.

inline SequenceNumber_t &operator+=(int inc) noexcept

Increase SequenceNumber.

Parameters:

inc – Number to add to the SequenceNumber

20.2.3.19.4. SequenceNumberDiff
struct SequenceNumberDiff
20.2.3.19.5. SequenceNumberHash
struct SequenceNumberHash

Defines the STL hash function for type SequenceNumber_t.

20.2.3.19.6. SequenceNumberSet_t
using eprosima::fastdds::rtps::SequenceNumberSet_t = BitmapRange<SequenceNumber_t, SequenceNumberDiff, 256>

Structure SequenceNumberSet_t, contains a group of sequencenumbers.

20.2.3.19.7. sort_seqNum
inline bool eprosima::fastdds::rtps::sort_seqNum(const SequenceNumber_t &s1, const SequenceNumber_t &s2) noexcept

Sorts two instances of SequenceNumber_t

Parameters:
Returns:

True if s1 is less than s2

20.2.3.20. SerializedPayload
20.2.3.20.1. Macro definitions (#define)
CDR_BE 0x0000
CDR_LE 0x0001
PL_CDR_BE 0x0002
PL_CDR_LE 0x0003
20.2.3.20.2. SerializedPayload_t
struct SerializedPayload_t

Structure SerializedPayload_t.

Public Functions

inline SerializedPayload_t()

Default constructor.

inline explicit SerializedPayload_t(uint32_t len)
Parameters:

len – Maximum size of the payload

SerializedPayload_t(const SerializedPayload_t &other) = delete

Copy constructor.

SerializedPayload_t &operator=(const SerializedPayload_t &other) = delete

Copy operator.

inline SerializedPayload_t(SerializedPayload_t &&other) noexcept

Move constructor.

SerializedPayload_t &operator=(SerializedPayload_t &&other) noexcept

Move operator.

~SerializedPayload_t()

Destructor It is expected to release the payload if the payload owner is not nullptr before destruction.

bool copy(const SerializedPayload_t *serData, bool with_limit = true)

Copy another structure (including allocating new space for the data).

Parameters:
  • serData[in] Pointer to the structure to copy

  • with_limit – if true, the function will fail when providing a payload too big

Returns:

True if correct

bool reserve_fragmented(SerializedPayload_t *serData)

Allocate new space for fragmented data.

Parameters:

serData[in] Pointer to the structure to copy

Returns:

True if correct

void empty()

Empty the payload.

Pre:

payload_owner must be nullptr

Public Members

uint16_t encapsulation

Encapsulation of the data as suggested in the RTPS 2.1 specification chapter 10.

uint32_t length

Actual length of the data.

octet *data

Pointer to the data.

uint32_t max_size

Maximum size of the payload.

uint32_t pos

Position when reading.

IPayloadPool *payload_owner = nullptr

Pool that created the payload.

Public Static Attributes

static constexpr size_t representation_header_size = 4u

Size in bytes of the representation header as specified in the RTPS 2.3 specification chapter 10.

20.2.3.21. RTPS Time_t
20.2.3.21.1. Macro definitions (#define)
TIME_T_INFINITE_SECONDS (eprosima::fastdds::dds::Time_t::INFINITE_SECONDS)
TIME_T_INFINITE_NANOSECONDS (eprosima::fastdds::dds::Time_t::INFINITE_NANOSECONDS)
20.2.3.21.2. Time_t RTPS Operators
static inline bool eprosima::fastdds::rtps::operator==(const Time_t &t1, const Time_t &t2)

Comparison assignment

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if equal

static inline bool eprosima::fastdds::rtps::operator!=(const Time_t &t1, const Time_t &t2)

Comparison assignment

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if not equal

static inline bool eprosima::fastdds::rtps::operator<(const Time_t &t1, const Time_t &t2)

Checks if a Time_t is less than other.

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if the first Time_t is less than the second

static inline bool eprosima::fastdds::rtps::operator>(const Time_t &t1, const Time_t &t2)

Checks if a Time_t is greater than other.

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if the first Time_t is greater than the second

static inline bool eprosima::fastdds::rtps::operator<=(const Time_t &t1, const Time_t &t2)

Checks if a Time_t is less or equal than other.

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if the first Time_t is less or equal than the second

static inline bool eprosima::fastdds::rtps::operator>=(const Time_t &t1, const Time_t &t2)

Checks if a Time_t is greater or equal than other.

Parameters:
  • t1 – First Time_t to compare

  • t2 – Second Time_t to compare

Returns:

True if the first Time_t is greater or equal than the second

inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const Time_t &t)
static inline Time_t eprosima::fastdds::rtps::operator+(const Time_t &ta, const Time_t &tb)

Adds two Time_t.

Parameters:
Returns:

A new Time_t with the result.

static inline Time_t eprosima::fastdds::rtps::operator-(const Time_t &ta, const Time_t &tb)

Subtracts two Time_t.

Parameters:
  • ta – First Time_t to subtract

  • tb – Second Time_t to subtract

Returns:

A new Time_t with the result.

20.2.3.21.3. RTPS layer Time_t
class Time_t

Structure Time_t, used to describe times at RTPS protocol.

Public Functions

Time_t() = default

Default constructor. Sets values to zero.

Time_t(int32_t sec, uint32_t frac)
Parameters:
  • sec – Seconds

  • frac – Fraction of second

Time_t(long double sec)
Parameters:

sec – Seconds. The fractional part is converted to nanoseconds.

Time_t(const eprosima::fastdds::dds::Time_t &time)
Parameters:

timefastdds::dds::Time_t, aka. dds::Duration_t.

int64_t to_ns() const

Returns stored time as nanoseconds (including seconds)

void from_ns(int64_t nanosecs)
Parameters:

nanosecs – Stores given time as nanoseconds (including seconds)

int32_t seconds() const

Retrieve the seconds field.

int32_t &seconds()

Retrieve the seconds field by ref.

void seconds(int32_t sec)

Sets seconds field.

uint32_t nanosec() const

Retrieve the nanosec field.

void nanosec(uint32_t nanos)

Sets nanoseconds field and updates the fraction.

uint32_t fraction() const

Retrieve the fraction field.

uint32_t &fraction()

Retrieve the fraction field by ref.

void fraction(uint32_t frac)

Sets fraction field and updates the nanoseconds.

Public Static Functions

static void now(Time_t &ret)

Fills a Time_t struct with a representation of the current time.

Parameters:

ret – Reference to the structure to be filled in.

20.2.3.22. Token
20.2.3.22.1. AuthenticatedPeerCredentialToken
typedef Token eprosima::fastdds::rtps::AuthenticatedPeerCredentialToken
20.2.3.22.2. DataHolder
class DataHolder
20.2.3.22.3. DataHolderHelper
class DataHolderHelper
20.2.3.22.4. DataHolderSeq
typedef std::vector<DataHolder> eprosima::fastdds::rtps::DataHolderSeq
20.2.3.22.5. IdentityStatusToken
typedef Token eprosima::fastdds::rtps::IdentityStatusToken
20.2.3.22.6. IdentityToken
typedef Token eprosima::fastdds::rtps::IdentityToken
20.2.3.22.7. PermissionsCredentialToken
typedef Token eprosima::fastdds::rtps::PermissionsCredentialToken
20.2.3.22.8. PermissionsToken
typedef Token eprosima::fastdds::rtps::PermissionsToken
20.2.3.22.9. Token
typedef DataHolder eprosima::fastdds::rtps::Token
20.2.3.23. Types
20.2.3.23.1. BuiltinEndpointSet_t
using eprosima::fastdds::rtps::BuiltinEndpointSet_t = uint32_t
20.2.3.23.2. Const values
const ProtocolVersion_t eprosima::fastdds::rtps::c_ProtocolVersion_2_0 = {2, 0}
const ProtocolVersion_t eprosima::fastdds::rtps::c_ProtocolVersion_2_1 = {2, 1}
const ProtocolVersion_t eprosima::fastdds::rtps::c_ProtocolVersion_2_2 = {2, 2}
const ProtocolVersion_t eprosima::fastdds::rtps::c_ProtocolVersion_2_3 = {2, 3}
const ProtocolVersion_t eprosima::fastdds::rtps::c_ProtocolVersion
const VendorId_t eprosima::fastdds::rtps::c_VendorId_Unknown = {0x00, 0x00}
const VendorId_t eprosima::fastdds::rtps::c_VendorId_eProsima = {0x01, 0x0F}
20.2.3.23.3. Count_t
using eprosima::fastdds::rtps::Count_t = uint32_t
20.2.3.23.4. Macro definitions (#define)
BIT0 0x01u
BIT1 0x02u
BIT2 0x04u
BIT3 0x08u
BIT4 0x10u
BIT5 0x20u
BIT6 0x40u
BIT7 0x80u
BIT(i) (1U << static_cast<unsigned>(i))
20.2.3.23.5. DurabilityKind_t
typedef enum eprosima::fastdds::rtps::DurabilityKind_t eprosima::fastdds::rtps::DurabilityKind_t

Durability kind.

20.2.3.23.6. Endianness_t
enum eprosima::fastdds::rtps::Endianness_t

This enumeration represents endianness types.

Values:

enumerator BIGEND

Big endianness.

enumerator LITTLEEND

Little endianness.

20.2.3.23.7. EndpointKind_t
typedef enum eprosima::fastdds::rtps::EndpointKind_t eprosima::fastdds::rtps::EndpointKind_t

Endpoint kind.

20.2.3.23.8. octet
using eprosima::fastdds::rtps::octet = unsigned char
20.2.3.23.9. ProtocolVersion_t
struct ProtocolVersion_t

Structure ProtocolVersion_t, contains the protocol version.

inline std::ostream &eprosima::fastdds::rtps::operator<<(std::ostream &output, const ProtocolVersion_t &pv)

Prints a ProtocolVersion

Parameters:
  • output – Output Stream

  • pv – ProtocolVersion

Returns:

OStream.

20.2.3.23.10. ReliabilityKind_t
typedef enum eprosima::fastdds::rtps::ReliabilityKind_t eprosima::fastdds::rtps::ReliabilityKind_t

Reliability enum used for internal purposes.

20.2.3.23.11. SubmessageFlag
using eprosima::fastdds::rtps::SubmessageFlag = unsigned char
20.2.3.23.12. TopicKind_t
typedef enum eprosima::fastdds::rtps::TopicKind_t eprosima::fastdds::rtps::TopicKind_t

Topic kind.

20.2.3.23.13. VendorId_t
using eprosima::fastdds::rtps::VendorId_t = std::array<uint8_t, 2>

Structure VendorId_t, specifying the vendor Id of the implementation.

20.2.3.24. WriteParams
class WriteParams

This class contains additional information of a CacheChange.

Public Functions

inline WriteParams &sample_identity(const SampleIdentity &sample_id)

Set the value of the sample_identity member.

Parameters:

sample_id – New value for the sample_identity member.

Returns:

Reference to the modified object in order to allow daisy chaining.

inline WriteParams &sample_identity(SampleIdentity &&sample_id)

Set the value of the sample_identity member.

Parameters:

sample_id – New value for the sample_identity member.

Returns:

Reference to the modified object in order to allow daisy chaining.

inline const SampleIdentity &sample_identity() const

Get the value of the sample_identity member.

Returns:

Constant reference to the sample_identity member.

inline SampleIdentity &sample_identity()

Set the value of the sample_identity member.

Returns:

Reference to the sample_identity member.

inline WriteParams &related_sample_identity(const SampleIdentity &sample_id)

Set the value of the related_sample_identity member of this class.

Parameters:

sample_id – New value for the related_sample_identity member.

Returns:

Reference to the modified object in order to allow daisy chaining.

inline WriteParams &related_sample_identity(SampleIdentity &&sample_id)

Set the related_sample_identity member of this class.

Parameters:

sample_id – New value for the related_sample_identity member.

Returns:

Reference to the modified object in order to allow daisy chaining.

inline const SampleIdentity &related_sample_identity() const

Get the value of the related_sample_identity member.

Returns:

Constant reference to the related_sample_identity member.

inline SampleIdentity &related_sample_identity()

Set the value of the related_sample_identity member.

Returns:

Reference to the related_sample_identity member.

inline Time_t source_timestamp() const

Get the value of the source_timestamp member.

Returns:

Current value of the source_timestamp member.

inline Time_t &source_timestamp()

Set the value of the source_timestamp member.

Returns:

Reference to the source_timestamp member.

inline WriteParams &source_timestamp(const Time_t &timestamp)

Set the source_timestamp member of this class.

Parameters:

timestamp – New value for the source_timestamp member.

Returns:

Reference to the modified object in order to allow daisy chaining.

inline WriteParams &source_timestamp(Time_t &&timestamp)

Set the source_timestamp member of this class.

Parameters:

timestamp – New value for the source_timestamp member.

Returns:

Reference to the modified object in order to allow daisy chaining.

Public Static Functions

static inline WriteParams write_params_default() noexcept

Default value for methods receiving a WriteParams.

Will contain the following values on its members:

Note

This should not return a reference to the static value if this value is meant to be read and written from different threads.

20.2.4. Endpoint

class Endpoint

Class Endpoint, all entities of the RTPS network derive from this class. Although the RTPSParticipant is also defined as an endpoint in the RTPS specification, in this implementation the RTPSParticipant class does not inherit from the endpoint class. Each Endpoint object owns a pointer to the RTPSParticipant it belongs to.

Subclassed by eprosima::fastdds::rtps::RTPSReader, eprosima::fastdds::rtps::RTPSWriter

Public Functions

inline const GUID_t &getGuid() const

Get associated GUID

Returns:

Associated GUID

inline RecursiveTimedMutex &getMutex()

Get mutex

Returns:

Associated Mutex

inline EndpointAttributes &getAttributes()

Get associated attributes

Returns:

Endpoint attributes

20.2.5. Flow control

20.2.5.1. FlowControllerDescriptor
struct FlowControllerDescriptor

Configuration values for creating flow controllers.

This descriptor is used to define the configuration applied in the creation of a flow controller.

Since

2.4.0

Public Members

std::string name = FASTDDS_FLOW_CONTROLLER_DEFAULT

Name of the flow controller.

FlowControllerSchedulerPolicy scheduler = FlowControllerSchedulerPolicy::FIFO

Scheduler policy used by the flow controller.

Default value: FlowControllerScheduler::FIFO_SCHEDULER

int32_t max_bytes_per_period = 0

Maximum number of bytes to be sent to network per period.

Range of bytes: [1, 2147483647]; 0 value means no limit. Default value: 0

uint64_t period_ms = 100

Period time in milliseconds.

Period of time on which the flow controller is allowed to send max_bytes_per_period. Default value: 100ms.

ThreadSettings sender_thread

Thread settings for the sender thread.

const char *const eprosima::fastdds::rtps::FASTDDS_FLOW_CONTROLLER_DEFAULT

Name of the default flow controller.

const char *const eprosima::fastdds::rtps::FASTDDS_STATISTICS_FLOW_CONTROLLER_DEFAULT

Name of the default flow controller for statistics writers.

20.2.5.2. FlowControllerSchedulerPolicy
enum class eprosima::fastdds::rtps::FlowControllerSchedulerPolicy : int32_t

Supported scheduler policy by a flow controller.

A flow controller’s scheduler policy takes the decision of which samples are the next ones to be sent to the network. Fast DDS flow controller supports several scheduler policies listed in this enumeration.

Values:

enumerator FIFO

FIFO scheduler policy: first written sample by user, first sample scheduled to be sent to network.

enumerator ROUND_ROBIN

Round Robin scheduler policy: schedules one sample of each DataWriter in circular order.

enumerator HIGH_PRIORITY

High priority scheduler policy: samples with highest priority are scheduled first to be sent to network.

enumerator PRIORITY_WITH_RESERVATION

Priority with reservation scheduler policy: guarantee each DataWriter’s minimum reservation of throughput. Samples not fitting the reservation are scheduled by priority.

20.2.6. History

20.2.6.1. History
class History

Class History, container of the different CacheChanges and the methods to access them.

Subclassed by eprosima::fastdds::rtps::ReaderHistory, eprosima::fastdds::rtps::WriterHistory

Public Functions

inline bool isFull()

Check if the history is full

Returns:

true if the History is full.

inline size_t getHistorySize()

Get the History size.

Returns:

Size of the history.

const_iterator find_change_nts(CacheChange_t *ch)

Find a specific change in the history using the matches_change method criteria. No Thread Safe

Parameters:

ch – Pointer to the CacheChange_t to search for.

Returns:

an iterator if a suitable change is found

virtual iterator remove_change_nts(const_iterator removal, bool release = true)

Remove a specific change from the history. No Thread Safe

Parameters:
  • removal – iterator to the CacheChange_t to remove.

  • release – defaults to true and hints if the CacheChange_t should return to the pool

Returns:

iterator to the next CacheChange_t or end iterator.

virtual iterator remove_change_nts(const_iterator removal, const std::chrono::time_point<std::chrono::steady_clock> &max_blocking_time, bool release = true)

Remove a specific change from the history. No Thread Safe

Parameters:
  • removal – iterator to the CacheChange_t to remove.

  • max_blocking_time[in] Maximum time this method has to complete the task.

  • release – defaults to true and hints if the CacheChange_t should return to the pool

Returns:

iterator to the next CacheChange_t or end iterator.

bool remove_all_changes()

Remove all changes from the History

Returns:

True if everything was correctly removed.

bool remove_change(CacheChange_t *ch)

Remove a specific change from the history.

Parameters:

ch – Pointer to the CacheChange_t.

Returns:

True if removed.

bool remove_change(CacheChange_t *ch, const std::chrono::time_point<std::chrono::steady_clock> &max_blocking_time)

Remove a specific change from the history.

Parameters:
  • ch – Pointer to the CacheChange_t.

  • max_blocking_time[in] Maximum time this method has to complete the task.

Returns:

True if removed.

inline const_iterator find_change(CacheChange_t *ch)

Find a specific change in the history using the matches_change method criteria.

Parameters:

ch – Pointer to the CacheChange_t to search for.

Returns:

an iterator if a suitable change is found

virtual bool matches_change(const CacheChange_t *ch_inner, CacheChange_t *ch_outer)

Verifies if an element of the changes collection matches a given change Derived classes have more info on how to identify univocally a change and should override.

Parameters:
  • ch_inner – element of the collection to compare with the given change

  • ch_outer – Pointer to the CacheChange_t to identify.

Returns:

true if the iterator identifies this change.

inline iterator remove_change(const_iterator removal, bool release = true)

Remove a specific change from the history.

Parameters:
  • removal – iterator to the CacheChange_t to remove.

  • release – defaults to true and hints if the CacheChange_t should return to the pool

Returns:

iterator to the next CacheChange_t or end iterator.

inline iterator changesBegin()

Get the beginning of the changes history iterator.

Returns:

Iterator to the beginning of the vector.

inline iterator changesEnd()

Get the end of the changes history iterator.

Returns:

Iterator to the end of the vector.

bool get_min_change(CacheChange_t **min_change)

Get the minimum CacheChange_t.

Parameters:

min_change – Pointer to pointer to the minimum change.

Returns:

True if correct.

bool get_max_change(CacheChange_t **max_change)

Get the maximum CacheChange_t.

Parameters:

max_change – Pointer to pointer to the maximum change.

Returns:

True if correct.

inline uint32_t getTypeMaxSerialized()

Get the maximum serialized payload size

Returns:

Maximum serialized payload size

inline RecursiveTimedMutex *getMutex() const

Get the mutex.

Returns:

Mutex

bool get_earliest_change(CacheChange_t **change)

A method to get the change with the earliest timestamp.

Parameters:

change – Pointer to pointer to earliest change

Returns:

True on success

Public Members

HistoryAttributes m_att

Attributes of the History.

20.2.6.2. IChangePool
class IChangePool

An interface for classes responsible of cache changes allocation management.

Public Functions

virtual bool reserve_cache(CacheChange_t *&cache_change) = 0

Get a new cache change from the pool.

Parameters:

cache_change[out] Pointer to the new cache change.

Returns:

whether the operation succeeded or not

Pre:

cache_change is nullptr

Post:

  • cache_change is not nullptr

  • *cache_change equals CacheChange_t() except for the contents of serializedPayload

virtual bool release_cache(CacheChange_t *cache_change) = 0

Return a cache change to the pool.

Parameters:

cache_change[in] Pointer to the cache change to release.

Returns:

whether the operation succeeded or not

Pre:

  • cache_change is not nullptr

  • cache_change points to a cache change obtained from a call to this->reserve_cache

20.2.6.3. IPayloadPool
class IPayloadPool

An interface for classes responsible of serialized payload management.

Public Functions

virtual bool get_payload(uint32_t size, SerializedPayload_t &payload) = 0

Get a serialized payload for a new sample.

This method will usually be called in one of the following situations:

  • When a writer creates a new cache change

  • When a reader receives the first fragment of a cache change

In both cases, the received size will be for the whole serialized payload.

Parameters:
  • size[in] Number of bytes required for the serialized payload.

  • payload[inout] Payload of the cache change used in the operation

Returns:

whether the operation succeeded or not

Post:

  • Field payload.payload_owner equals this

  • Field payload.data points to a buffer of at least size bytes

  • Field payload.max_size is greater than or equal to size

virtual bool get_payload(const SerializedPayload_t &data, SerializedPayload_t &payload) = 0

Assign a serialized payload to a new sample.

This method will usually be called when a reader receives a whole cache change.

Note

If data has no owner, it means it is allocated on the stack of a reception thread, and a copy should be performed. If the ownership of data needs to be changed, a consecutive call to this method needs to be performed with the arguments swapped, leveraging the post-condition of this method which ensures that payload.payload_owner points to this.

Parameters:
  • data[inout] Serialized payload received

  • payload[inout] Destination serialized payload

Returns:

whether the operation succeeded or not

Post:

  • Field payload.payload_owner equals this

  • Field payload.data points to a buffer of at least data.length bytes

  • Field payload.length is equal to data.length

  • Field payload.max_size is greater than or equal to data.length

  • Content of payload.data is the same as data.data

virtual bool release_payload(SerializedPayload_t &payload) = 0

Release a serialized payload from a sample.

This method will be called when a cache change is removed from a history.

Parameters:

payload[inout] Payload to be released

Returns:

whether the operation succeeded or not

Pre:

  • Field payload_owner of payload equals this

Post:

  • Field payload_owner of payload is nullptr

20.2.6.4. ReaderHistory
class ReaderHistory : public eprosima::fastdds::rtps::History

Class ReaderHistory, container of the different CacheChanges of a reader

Public Functions

ReaderHistory(const HistoryAttributes &att)

Constructor of the ReaderHistory. It needs a HistoryAttributes.

virtual bool can_change_be_added_nts(const GUID_t &writer_guid, uint32_t total_payload_size, size_t unknown_missing_changes_up_to, bool &will_never_be_accepted) const

Check if a new change can be added to this history.

Parameters:
  • writer_guid[in] GUID of the writer where the change came from.

  • total_payload_size[in] Total payload size of the incoming change.

  • unknown_missing_changes_up_to[in] The number of changes from the same writer with a lower sequence number that could potentially be received in the future.

  • will_never_be_accepted[out] When the method returns false, this parameter will inform whether the change could be accepted in the future or not.

Pre:

change should not be present in the history

Returns:

Whether a call to received_change will succeed when called with the same arguments.

virtual bool received_change(CacheChange_t *change, size_t unknown_missing_changes_up_to)

Virtual method that is called when a new change is received. In this implementation this method just calls add_change. The user can overload this method in case he needs to perform additional checks before adding the change.

Parameters:
  • change – Pointer to the change

  • unknown_missing_changes_up_to – The number of changes from the same writer with a lower sequence number that could potentially be received in the future.

Returns:

True if added.

inline virtual bool received_change(CacheChange_t *change, size_t unknown_missing_changes_up_to, fastdds::dds::SampleRejectedStatusKind &rejection_reason)

Virtual method that is called when a new change is received. In this implementation this method just calls add_change. The user can overload this method in case he needs to perform additional checks before adding the change.

Parameters:
  • change[in] Pointer to the change

  • unknown_missing_changes_up_to[in] The number of changes from the same writer with a lower sequence number that could potentially be received in the future.

  • rejection_reason[out] In case of been rejected the sample, it will contain the reason of the rejection.

Returns:

True if added.

inline virtual bool completed_change(rtps::CacheChange_t *change)

Called when a fragmented change is received completely by the Subscriber. Will find its instance and store it.

Parameters:

change[in] The received change

Pre:

Change should be already present in the history.

Returns:

inline virtual bool completed_change(CacheChange_t *change, size_t unknown_missing_changes_up_to, fastdds::dds::SampleRejectedStatusKind &rejection_reason)

Called when a fragmented change is received completely by the Subscriber. Will find its instance and store it.

Parameters:
  • change[in] The received change

  • unknown_missing_changes_up_to[in] Number of missing changes before this one

  • rejection_reason[out] In case of been rejected the sample, it will contain the reason of the rejection.

Pre:

Change should be already present in the history.

Returns:

bool add_change(CacheChange_t *a_change)

Add a CacheChange_t to the ReaderHistory.

Parameters:

a_change – Pointer to the CacheChange to add.

Returns:

True if added.

virtual iterator remove_change_nts(const_iterator removal, bool release = true) override

Remove a specific change from the history. No Thread Safe

Parameters:
  • removal – iterator to the change for removal

  • release – specifies if the change must be returned to the pool

Returns:

iterator to the next change if any

virtual iterator remove_change_nts(const_iterator removal, const std::chrono::time_point<std::chrono::steady_clock> &max_blocking_time, bool release = true) override

Remove a specific change from the history. No Thread Safe

Parameters:
  • removal – iterator to the change for removal

  • max_blocking_time[in] Maximum time this method has to complete the task.

  • release – specifies if the change must be returned to the pool

Returns:

iterator to the next change if any

virtual bool matches_change(const CacheChange_t *inner, CacheChange_t *outer) override

Criteria to search a specific CacheChange_t on history

Parameters:
  • inner – change to compare

  • outer – change for comparison

Returns:

true if inner matches outer criteria

bool remove_changes_with_guid(const GUID_t &a_guid)

Remove all changes from the History that have a certain guid.

Parameters:

a_guid – Pointer to the target guid to search for.

Returns:

True if successful, even if no changes have been removed.

bool remove_fragmented_changes_until(const SequenceNumber_t &seq_num, const GUID_t &writer_guid)

Remove all fragmented changes from certain writer up to certain sequence number.

Parameters:
  • seq_num – First SequenceNumber_t not to be removed.

  • writer_guid – GUID of the writer for which changes should be looked for.

Returns:

True if successful, even if no changes have been removed.

virtual void writer_unmatched(const GUID_t &writer_guid, const SequenceNumber_t &last_notified_seq)

Called when a writer is unmatched from the reader holding this history.

This method will remove all the changes on the history that came from the writer being unmatched and which have not yet been notified to the user.

Parameters:
  • writer_guid – GUID of the writer being unmatched.

  • last_notified_seq – Last sequence number from the specified writer that was notified to the user.

inline virtual void writer_update_its_ownership_strength_nts(const GUID_t &writer_guid, const uint32_t ownership_strength)

This function should be called by reader if a writer updates its ownership strength.

Parameters:
  • writer_guid[in] Guid of the writer which changes its ownership strength.

  • ownership_strength[out] New value of the writer’s Ownership strength.

bool remove_change(CacheChange_t *ch)

Introduce base class method into scope.

bool remove_change(CacheChange_t *ch, const std::chrono::time_point<std::chrono::steady_clock> &max_blocking_time)

Introduce base class method into scope.

inline iterator remove_change(const_iterator removal, bool release = true)

Introduce base class method into scope.

20.2.6.5. WriterHistory
class WriterHistory : public eprosima::fastdds::rtps::History

Class WriterHistory, container of the different CacheChanges of a writer

Public Functions

WriterHistory(const HistoryAttributes &att)

Construct a WriterHistory.

Parameters:

att – Attributes configuring the WriterHistory.

WriterHistory(const HistoryAttributes &att, const std::shared_ptr<IPayloadPool> &payload_pool)

Construct a WriterHistory with a custom payload pool.

Parameters:
WriterHistory(const HistoryAttributes &att, const std::shared_ptr<IPayloadPool> &payload_pool, const std::shared_ptr<IChangePool> &change_pool)

Construct a WriterHistory with custom payload and change pools.

Parameters:
const std::shared_ptr<IPayloadPool> &get_payload_pool() const

Get the payload pool used by this history.

Returns:

Reference to the payload pool used by this history.

const std::shared_ptr<IChangePool> &get_change_pool() const

Get the change pool used by this history.

Returns:

Reference to the change pool used by this history.

CacheChange_t *create_change(ChangeKind_t change_kind, InstanceHandle_t handle = c_InstanceHandle_Unknown)

Create a new CacheChange_t object.

Parameters:
  • change_kind – Kind of the change.

  • handleInstanceHandle_t of the change.

Returns:

Pointer to the new CacheChange_t object.

Pre:

A writer has been associated with this history

CacheChange_t *create_change(uint32_t payload_size, ChangeKind_t change_kind, InstanceHandle_t handle = c_InstanceHandle_Unknown)

Create a new CacheChange_t object with a specific payload size.

Parameters:
  • payload_size – Size of the payload.

  • change_kind – Kind of the change.

  • handleInstanceHandle_t of the change.

Returns:

Pointer to the new CacheChange_t object.

Pre:

A writer has been associated with this history

bool add_change(CacheChange_t *a_change)

Add a CacheChange_t to the WriterHistory.

Parameters:

a_change – Pointer to the CacheChange_t to be added.

Returns:

True if added.

bool add_change(CacheChange_t *a_change, WriteParams &wparams)

Add a CacheChange_t to the WriterHistory.

Parameters:
  • a_change – Pointer to the CacheChange_t to be added.

  • wparams – Extra write parameters.

Returns:

True if added.

virtual iterator remove_change_nts(const_iterator removal, bool release = true) override

Remove a specific change from the history. No Thread Safe

Parameters:
  • removal – iterator to the change for removal

  • release – specifies if the change should be return to the pool

Returns:

iterator to the next change if any

virtual iterator remove_change_nts(const_iterator removal, const std::chrono::time_point<std::chrono::steady_clock> &max_blocking_time, bool release = true) override

Remove a specific change from the history. No Thread Safe

Parameters:
  • removal – iterator to the change for removal

  • release – specifies if the change should be return to the pool

  • max_blocking_time[in] Maximum time this method has to complete the task.

Returns:

iterator to the next change if any

virtual bool matches_change(const CacheChange_t *inner, CacheChange_t *outer) override

Criteria to search a specific CacheChange_t on history

Parameters:
  • inner – change to compare

  • outer – change for comparison

Returns:

true if inner matches outer criteria

bool remove_min_change()

Remove the CacheChange_t with the minimum sequenceNumber.

Returns:

True if correctly removed.

bool remove_min_change(const std::chrono::time_point<std::chrono::steady_clock> &max_blocking_time)

Remove the CacheChange_t with the minimum sequenceNumber.

Parameters:

max_blocking_time[in] Maximum time this method has to complete the task.

Returns:

True if correctly removed.

bool release_change(CacheChange_t *ch)

Release a change when it is not being used anymore.

Parameters:

ch – Pointer to the cache change to be released.

Returns:

whether the operation succeeded or not

Pre:

  • A writer has been associated with this history

  • ch is not nullptr

  • ch points to a cache change obtained from a call to this->create_change

Post:

memory pointed to by ch is not accessed

bool remove_change(CacheChange_t *ch)

Introduce base class method into scope.

bool remove_change(CacheChange_t *ch, const std::chrono::time_point<std::chrono::steady_clock> &max_blocking_time)

Introduce base class method into scope.

inline iterator remove_change(const_iterator removal, bool release = true)

Introduce base class method into scope.

20.2.7. RTPSParticipant

20.2.7.1. ParticipantDiscoveryInfo
20.2.7.1.1. ParticipantAuthenticationInfo
struct ParticipantAuthenticationInfo

Public Members

AUTHENTICATION_STATUS status

Status.

GUID_t guid

Associated GUID.

inline bool eprosima::fastdds::rtps::operator==(const ParticipantAuthenticationInfo &l, const ParticipantAuthenticationInfo &r)
20.2.7.1.2. ParticipantDiscoveryStatus
enum class eprosima::fastdds::rtps::ParticipantDiscoveryStatus

Enum ParticipantDiscoveryStatus, four different status for discovered participants.

Values:

enumerator DISCOVERED_PARTICIPANT
enumerator CHANGED_QOS_PARTICIPANT
enumerator REMOVED_PARTICIPANT
enumerator DROPPED_PARTICIPANT
enumerator IGNORED_PARTICIPANT
20.2.7.1.3. ReaderDiscoveryStatus
enum class eprosima::fastdds::rtps::ReaderDiscoveryStatus

Enum DISCOVERY_STATUS, four different status for discovered readers.

Values:

enumerator DISCOVERED_READER
enumerator CHANGED_QOS_READER
enumerator REMOVED_READER
enumerator IGNORED_READER
20.2.7.1.4. WriterDiscoveryStatus
enum class eprosima::fastdds::rtps::WriterDiscoveryStatus

Enum WriterDiscoveryStatus, four different status for discovered writers.

Values:

enumerator DISCOVERED_WRITER
enumerator CHANGED_QOS_WRITER
enumerator REMOVED_WRITER
enumerator IGNORED_WRITER
20.2.7.2. RTPSParticipant
class RTPSParticipant

Class RTPSParticipant, contains the public API for a RTPSParticipant.

Public Functions

const GUID_t &getGuid() const

Get the GUID_t of the RTPSParticipant.

void announceRTPSParticipantState()

Force the announcement of the RTPSParticipant state.

void stopRTPSParticipantAnnouncement()

Stop the RTPSParticipant announcement period. //TODO remove this method because is only for testing.

void resetRTPSParticipantAnnouncement()

Reset the RTPSParticipant announcement period. //TODO remove this method because is only for testing.

bool newRemoteWriterDiscovered(const GUID_t &pguid, int16_t userDefinedId)

Indicate the Participant that you have discovered a new Remote Writer. This method can be used by the user to implements its own Static Endpoint Discovery Protocol

Parameters:
  • pguidGUID_t of the discovered Writer.

  • userDefinedId – ID of the discovered Writer.

Returns:

True if correctly added.

bool newRemoteReaderDiscovered(const GUID_t &pguid, int16_t userDefinedId)

Indicate the Participant that you have discovered a new Remote Reader. This method can be used by the user to implements its own Static Endpoint Discovery Protocol

Parameters:
  • pguidGUID_t of the discovered Reader.

  • userDefinedId – ID of the discovered Reader.

Returns:

True if correctly added.

uint32_t getRTPSParticipantID() const

Get the Participant ID.

Returns:

Participant ID.

bool register_writer(RTPSWriter *rtps_writer, const TopicDescription &topic, const fastdds::dds::WriterQos &qos)

Register a Writer in the BuiltinProtocols.

Parameters:
  • rtps_writer – Pointer to the RTPSWriter.

  • topic – Information regarding the topic where the writer is registering.

  • qos – Qos policies of the writer.

Returns:

True if correctly registered.

bool register_reader(RTPSReader *rtps_reader, const TopicDescription &topic, const fastdds::dds::ReaderQos &qos, const ContentFilterProperty *content_filter = nullptr)

Register a Reader in the BuiltinProtocols.

Parameters:
  • rtps_reader – Pointer to the RTPSReader.

  • topic – Information regarding the topic where the reader is registering.

  • qos – Qos policies of the reader.

  • content_filter – Optional content filtering information.

Returns:

True if correctly registered.

void update_attributes(const RTPSParticipantAttributes &patt)

Update participant attributes.

Parameters:

patt – New participant attributes.

bool update_writer(RTPSWriter *rtps_writer, const fastdds::dds::WriterQos &wqos)

Update local writer QoS

Parameters:
  • rtps_writer – Writer to update.

  • wqos – New QoS for the writer.

Returns:

True on success

bool update_reader(RTPSReader *rtps_reader, const fastdds::dds::ReaderQos &rqos, const ContentFilterProperty *content_filter = nullptr)

Update local reader QoS

Parameters:
  • rtps_reader – Reader to update.

  • rqos – New QoS for the reader.

  • content_filter – Optional content filtering information.

Returns:

True on success

std::vector<std::string> getParticipantNames() const

Returns a list with the participant names.

Returns:

list of participant names.

const RTPSParticipantAttributes &get_attributes() const

Get a reference of the current state of the RTPSParticipantParameters.

Returns:

RTPSParticipantAttributes reference.

uint32_t getMaxMessageSize() const

Retrieves the maximum message size.

uint32_t getMaxDataSize() const

Retrieves the maximum data size.

WLP *wlp() const

A method to retrieve the built-in writer liveliness protocol.

Returns:

Writer liveliness protocol

bool get_new_entity_id(EntityId_t &entityId)

Fills a new entityId if set to unknown, or checks if a entity already exists with that entityId in other case.

Parameters:

entityId – to check of fill. If filled, EntityKind will be “vendor-specific” (0x01)

Returns:

True if filled or the entityId is available.

void set_check_type_function(std::function<bool(const std::string&)> &&check_type)

Allows setting a function to check if a type is already known by the top level API participant.

void set_listener(RTPSParticipantListener *listener)

Modifies the participant listener.

Parameters:

listener

uint32_t get_domain_id() const

Retrieves the DomainId.

void enable()

This operation enables the RTPSParticipantImpl.

bool ignore_participant(const GuidPrefix_t &participant_guid)

Ignore all messages coming from the RTPSParticipant.

Parameters:

participant_guid[in] RTPSParticipant GUID to be ignored

Returns:

True if correctly included into the ignore collection. False otherwise.

bool ignore_writer(const GUID_t &writer_guid)

Ignore all messages coming from the RTPSWriter.

Parameters:

writer_guid[in] RTPSWriter GUID to be ignored

Returns:

True if correctly included into the ignore collection. False otherwise.

bool ignore_reader(const GUID_t &reader_guid)

Ignore all messages coming from the RTPSReader.

Parameters:

reader_guid[in] RTPSReader GUID to be ignored

Returns:

True if correctly included into the ignore collection. False otherwise.

std::vector<TransportNetmaskFilterInfo> get_netmask_filter_info() const

Returns registered transports’ netmask filter information (transport’s netmask filter kind and allowlist).

Returns:

A vector with all registered transports’ netmask filter information.

bool get_publication_info(fastdds::rtps::PublicationBuiltinTopicData &data, const GUID_t &writer_guid) const

Fills the provided publication discovery data with the information of the writer identified by writer_guid.

Parameters:
  • data[out] publication discovery data to fill.

  • writer_guid[in] GUID of the writer to get the information from.

Returns:

True if the writer was found and the data was filled.

bool get_subscription_info(fastdds::rtps::SubscriptionBuiltinTopicData &data, const GUID_t &reader_guid) const

Fills the provided subscription discovery data with the information of the reader identified by reader_guid.

Parameters:
  • data[out] subscription discovery data to fill.

  • reader_guid[in] GUID of the reader to get the information from.

Returns:

True if the reader was found and the data was filled.

bool is_security_enabled_for_writer(const WriterAttributes &writer_attributes)

Checks whether the writer has security attributes enabled.

Parameters:

writer_attributes – Attributes of the writer as given to the RTPSParticipantImpl::create_writer

bool is_security_enabled_for_reader(const ReaderAttributes &reader_attributes)

Checks whether the reader has security attributes enabled.

Parameters:

reader_attributes – Attributes of the reader as given to the RTPSParticipantImpl::create_reader

20.2.7.3. RTPSParticipantListener
class RTPSParticipantListener

Class RTPSParticipantListener with virtual method that the user can overload to respond to certain events.

Public Functions

inline virtual void on_participant_discovery(RTPSParticipant *participant, ParticipantDiscoveryStatus reason, const ParticipantBuiltinTopicData &info, bool &should_be_ignored)

This method is called when a new Participant is discovered, or a previously discovered participant changes its QOS or is removed.

Parameters:
  • participant[out] Pointer to the Participant which discovered the remote participant.

  • reason[out] Reason of the change in the status of the discovered participant.

  • info[out] Remote participant information. User can take ownership of the object.

  • should_be_ignored[out] Flag to indicate the library to automatically ignore the discovered Participant.

inline virtual void on_reader_discovery(RTPSParticipant *participant, ReaderDiscoveryStatus reason, const SubscriptionBuiltinTopicData &info, bool &should_be_ignored)

This method is called when a new Reader is discovered, or a previously discovered reader changes its QOS or is removed.

Parameters:
  • participant[in] Pointer to the Participant which discovered the remote reader.

  • reason[in] The reason motivating this method to be called.

  • info[in] Remote reader information.

  • should_be_ignored[out] Flag to indicate the library to automatically ignore the discovered reader.

inline virtual void on_writer_discovery(RTPSParticipant *participant, WriterDiscoveryStatus reason, const PublicationBuiltinTopicData &info, bool &should_be_ignored)

This method is called when a new Writer is discovered, or a previously discovered writer changes its QOS or is removed.

Parameters:
  • participant[in] Pointer to the Participant which discovered the remote writer.

  • reason[in] The reason motivating this method to be called.

  • info[in] Remote writer information.

  • should_be_ignored[out] Flag to indicate the library to automatically ignore the discovered writer.

20.2.8. RTPSReader

20.2.8.1. ReaderListener
class ReaderListener

Class ReaderListener, to be used by the user to override some of is virtual method to program actions to certain events.

Public Functions

inline virtual void on_reader_matched(RTPSReader *reader, const MatchingInfo &info)

This method is invoked when a new reader matches

Parameters:
  • reader – Matching reader

  • info – Matching information of the reader

inline virtual void on_new_cache_change_added(RTPSReader *reader, const CacheChange_t *const change)

This method is called when a new CacheChange_t is added to the ReaderHistory.

Parameters:
  • reader – Pointer to the reader.

  • change – Pointer to the CacheChange_t. This is a const pointer to const data to indicate that the user should not dispose of this data himself. To remove the data call the remove_change method of the ReaderHistory. reader->get_history()->remove_change((CacheChange_t*)change).

inline virtual void on_liveliness_changed(RTPSReader *reader, const eprosima::fastdds::dds::LivelinessChangedStatus &status)

Method called when the liveliness of a reader changes.

Parameters:
  • reader – The reader

  • status – The liveliness changed status

inline virtual void on_requested_incompatible_qos(RTPSReader *reader, eprosima::fastdds::dds::PolicyMask qos)

This method is called when a new Writer is discovered, with a Topic that matches that of a local reader, but with an offered QoS that is incompatible with the one requested by the local reader

Parameters:
  • reader – Pointer to the RTPSReader.

  • qos – A mask with the bits of all incompatible Qos activated.

inline virtual void on_sample_lost(RTPSReader *reader, int32_t sample_lost_since_last_update)

This method is called when the reader detects that one or more samples have been lost.

Parameters:
  • reader – Pointer to the RTPSReader.

  • sample_lost_since_last_update – The number of samples that were lost since the last time this method was called for the same reader.

inline virtual void on_writer_discovery(RTPSReader *reader, WriterDiscoveryStatus reason, const GUID_t &writer_guid, const PublicationBuiltinTopicData *writer_info)

Method called when the discovery information of a writer regarding a reader changes.

Parameters:
  • reader – The reader.

  • reason – The reason motivating this method to be called.

  • writer_guid – The GUID of the writer for which the discovery information changed.

  • writer_info – Discovery information about the writer. Will be nullptr for reason REMOVED_WRITER.

inline virtual void on_sample_rejected(RTPSReader *reader, eprosima::fastdds::dds::SampleRejectedStatusKind reason, const CacheChange_t *const change)

This method is called when the reader rejects a samples.

Parameters:
  • reader – Pointer to the RTPSReader.

  • reason – Indicates reason for sample rejection.

  • change – Pointer to the CacheChange_t. This is a const pointer to const data to indicate that the user should not dispose of this data himself.

inline virtual void on_data_available(RTPSReader *reader, const GUID_t &writer_guid, const SequenceNumber_t &first_sequence, const SequenceNumber_t &last_sequence, bool &should_notify_individual_changes)

This method is called when new CacheChange_t objects are made available to the user.

Note

This method is currently never called. Implementation will be added in future releases.

Parameters:
  • reader[in] Pointer to the reader performing the notification.

  • writer_guid[in] GUID of the writer from which the changes were received.

  • first_sequence[in] Sequence number of the first change made available.

  • last_sequence[in] Sequence number of the last change made available. It will always be greater or equal than first_sequence.

  • should_notify_individual_changes[out] Whether the individual changes should be notified by means of on_new_cache_change_added.

inline virtual void on_incompatible_type(RTPSReader *reader)

This method is called when a new Writer is discovered, with a Topic that matches the name of a local reader, but with an incompatible type

Parameters:

reader – Pointer to the RTPSReader.

20.2.8.2. RTPSReader
class RTPSReader : public eprosima::fastdds::rtps::Endpoint

Class RTPSReader, manages the reception of data from its matched writers. Needs to be constructed using the createRTPSReader method from the RTPSDomain.

Public Functions

virtual bool matched_writer_add(const PublicationBuiltinTopicData &info) = 0

Add a matched writer represented by its publication info.

Parameters:

info – Publication info of the writer being matched.

Returns:

True if correctly added.

virtual bool matched_writer_remove(const GUID_t &writer_guid, bool removed_by_lease = false) = 0

Remove a writer from the matched writers.

Parameters:
  • writer_guid – GUID of the writer to remove.

  • removed_by_lease – Whether the writer is being unmatched due to a participant drop.

Returns:

True if correctly removed.

virtual bool matched_writer_is_matched(const GUID_t &writer_guid) = 0

Check if a specific writer is matched against this reader.

Parameters:

writer_guid – GUID of the writer to check.

Returns:

True if the specified writer is matched with this reader.

virtual void assert_writer_liveliness(const GUID_t &writer) = 0

Assert the liveliness of a matched writer.

Parameters:

writer – GUID of the writer on which to assert liveliness.

virtual bool is_in_clean_state() = 0

Check if this reader is in a clean state with all its matched writers. This will happen when the reader has received all samples announced by all its matched writers.

Returns:

Whether the reader is in a clean state with all its matched writers.

virtual ReaderListener *get_listener() const = 0

Get the associated listener.

Returns:

Pointer to the associated reader listener.

virtual void set_listener(ReaderListener *listener) = 0

Change the listener associated to this reader.

Parameters:

listener – The new listener to associate to this reader.

virtual bool expects_inline_qos() const = 0
Returns:

True if the reader expects Inline QoS.

virtual ReaderHistory *get_history() const = 0
Returns:

a pointer to the associated History.

virtual eprosima::fastdds::rtps::IReaderDataFilter *get_content_filter() const = 0
Returns:

The content filter associated to this reader.

virtual void set_content_filter(eprosima::fastdds::rtps::IReaderDataFilter *filter) = 0

Set the content filter associated to this reader.

Parameters:

filter – Pointer to the content filter to associate to this reader.

virtual bool matched_writers_guids(std::vector<GUID_t> &guids) const = 0

Fills the provided vector with the GUIDs of the matched writers.

Parameters:

guids[out] Vector to be filled with the GUIDs of the matched writers.

Returns:

True if the operation was successful.

virtual CacheChange_t *next_unread_cache() = 0

Read the next unread CacheChange_t from the history.

Returns:

A pointer to the first unread CacheChange_t from the history.

virtual CacheChange_t *next_untaken_cache() = 0

Get the next CacheChange_t from the history to take.

Returns:

A pointer to the first CacheChange_t in the history.

virtual bool wait_for_unread_cache(const eprosima::fastdds::dds::Duration_t &timeout) = 0

Wait until there is an unread CacheChange_t in the history.

Parameters:

timeout – Maximum time to wait.

Returns:

true if there is an unread CacheChange_t in the history.

virtual uint64_t get_unread_count() const = 0

Get the number of unread CacheChange_t in the history.

Returns:

The number of unread CacheChange_t in the history.

virtual uint64_t get_unread_count(bool mark_as_read) = 0

Get the number of unread CacheChange_t in the history and optionally mark them as read.

Parameters:

mark_as_read – Whether to mark the unread CacheChange_t as read.

Returns:

The number of previously unread CacheChange_t in the history.

virtual bool is_sample_valid(const void *data, const GUID_t &writer, const SequenceNumber_t &sn) const = 0

Checks whether the sample is still valid or is corrupted.

Parameters:
  • data – Pointer to the sample data to check. If it does not belong to the payload pool passed to the reader on construction, it yields undefined behavior.

  • writer – GUID of the writer that sent data.

  • sn – Sequence number related to data.

Returns:

true if the sample is valid

20.2.9. Resources

20.2.9.1. MemoryManagementPolicy
enum eprosima::fastdds::rtps::MemoryManagementPolicy

Enum MemoryuManagementPolicy_t, indicated the way memory is managed in terms of dealing with CacheChanges

Values:

enumerator PREALLOCATED_MEMORY_MODE

Preallocated memory.

Size set to the data type maximum. Largest memory footprint but smallest allocation count.

enumerator PREALLOCATED_WITH_REALLOC_MEMORY_MODE

Default size preallocated, requires reallocation when a bigger message arrives.

Smaller memory footprint at the cost of an increased allocation count.

enumerator DYNAMIC_RESERVE_MEMORY_MODE
enumerator DYNAMIC_REUSABLE_MEMORY_MODE

20.2.10. RTPSDomain

class RTPSDomain

Class RTPSDomain,it manages the creation and destruction of RTPSParticipant RTPSWriter and RTPSReader. It stores a list of all created RTPSParticipant. It has only static methods.

Public Static Functions

static void set_filewatch_thread_config(const fastdds::rtps::ThreadSettings &watch_thread, const fastdds::rtps::ThreadSettings &callback_thread)

Method to set the configuration of the threads created by the file watcher for the environment file. In order for these settings to take effect, this method must be called before the first call to createParticipant.

Parameters:
  • watch_thread – Settings for the thread watching the environment file.

  • callback_thread – Settings for the thread executing the callback when the environment file changed.

static void stopAll()

Method to shut down all RTPSParticipants, readers, writers, etc. It must be called at the end of the process to avoid memory leaks. It also shut downs the DomainRTPSParticipant.

Post:

After this call, all the pointers to RTPS entities are invalidated and their use may result in undefined behaviour.

static RTPSParticipant *createParticipant(uint32_t domain_id, const RTPSParticipantAttributes &attrs, RTPSParticipantListener *plisten = nullptr)

Create a RTPSParticipant.

Warning

The returned pointer is invalidated after a call to removeRTPSParticipant() or stopAll(), so its use may result in undefined behaviour.

Parameters:
  • domain_id – DomainId to be used by the RTPSParticipant (80 by default).

  • attrsRTPSParticipant Attributes.

  • plisten – Pointer to the ParticipantListener.

Returns:

Pointer to the RTPSParticipant.

static RTPSParticipant *createParticipant(uint32_t domain_id, bool enabled, const RTPSParticipantAttributes &attrs, RTPSParticipantListener *plisten = nullptr)

Create a RTPSParticipant.

Warning

The returned pointer is invalidated after a call to removeRTPSParticipant() or stopAll(), so its use may result in undefined behaviour.

Parameters:
Returns:

Pointer to the RTPSParticipant.

static RTPSParticipant *create_client_server_participant(uint32_t domain_id, bool enabled, const RTPSParticipantAttributes &attrs, RTPSParticipantListener *plisten = nullptr)

Create a RTPSParticipant as default server or client if ROS_MASTER_URI environment variable is set. It also configures ROS 2 Easy Mode IP if ROS2_EASY_MODE_URI environment variable is set and it was empty in the input attributes.

Warning

The returned pointer is invalidated after a call to removeRTPSParticipant() or stopAll(), so its use may result in undefined behaviour.

Parameters:
Returns:

Pointer to the RTPSParticipant.

static RTPSWriter *createRTPSWriter(RTPSParticipant *p, WriterAttributes &watt, WriterHistory *hist, WriterListener *listen = nullptr)

Create a RTPSWriter in a participant.

Warning

The returned pointer is invalidated after a call to removeRTPSWriter() or stopAll(), so its use may result in undefined behaviour.

Parameters:
Returns:

Pointer to the created RTPSWriter.

static RTPSWriter *createRTPSWriter(RTPSParticipant *p, const EntityId_t &entity_id, WriterAttributes &watt, WriterHistory *hist, WriterListener *listen = nullptr)

Create a RTPSWriter in a participant.

Warning

The returned pointer is invalidated after a call to removeRTPSWriter() or stopAll(), so its use may result in undefined behaviour.

Parameters:
  • p – Pointer to the RTPSParticipant.

  • entity_id – Specific entity id to use for the created writer.

  • watt – Writer Attributes.

  • hist – Pointer to the WriterHistory.

  • listen – Pointer to the WriterListener.

Returns:

Pointer to the created RTPSWriter.

static bool removeRTPSWriter(RTPSWriter *writer)

Remove a RTPSWriter.

Parameters:

writer – Pointer to the writer you want to remove.

Returns:

True if correctly removed.

static RTPSReader *createRTPSReader(RTPSParticipant *p, ReaderAttributes &ratt, ReaderHistory *hist, ReaderListener *listen = nullptr)

Create a RTPSReader in a participant.

Warning

The returned pointer is invalidated after a call to removeRTPSReader() or stopAll(), so its use may result in undefined behaviour.

Parameters:
Returns:

Pointer to the created RTPSReader.

static RTPSReader *createRTPSReader(RTPSParticipant *p, ReaderAttributes &ratt, const std::shared_ptr<IPayloadPool> &payload_pool, ReaderHistory *hist, ReaderListener *listen = nullptr)

Create a RTPReader in a participant using a custom payload pool.

Warning

The returned pointer is invalidated after a call to removeRTPSReader() or stopAll(), so its use may result in undefined behaviour.

Parameters:
Returns:

Pointer to the created RTPSReader.

static RTPSReader *createRTPSReader(RTPSParticipant *p, const EntityId_t &entity_id, ReaderAttributes &ratt, const std::shared_ptr<IPayloadPool> &payload_pool, ReaderHistory *hist, ReaderListener *listen = nullptr)

Create a RTPSReader in a participant using a custom payload pool.

Warning

The returned pointer is invalidated after a call to removeRTPSReader() or stopAll(), so its use may result in undefined behaviour.

Parameters:
Returns:

Pointer to the created RTPSReader.

static bool removeRTPSReader(RTPSReader *reader)

Remove a RTPSReader.

Parameters:

reader – Pointer to the reader you want to remove.

Returns:

True if correctly removed.

static bool removeRTPSParticipant(RTPSParticipant *p)

Remove a RTPSParticipant and delete all its associated Writers, Readers, resources, etc.

Parameters:

p[in] Pointer to the RTPSParticipant;

Returns:

True if correct.

static bool get_library_settings(fastdds::LibrarySettings &library_settings)

Get the library settings.

Parameters:

library_settings – LibrarySettings reference where the settings are returned.

Returns:

True.

static bool set_library_settings(const fastdds::LibrarySettings &library_settings)

Set the library settings-.

Parameters:

library_settings – LibrarySettings to be set.

Returns:

False if there is any RTPSParticipant already created. True if correctly set.

20.2.11. RTPSWriter

20.2.11.1. RTPSWriter
class RTPSWriter : public eprosima::fastdds::rtps::Endpoint

Class RTPSWriter, manages the sending of data to the readers. Is always associated with a HistoryCache.

Public Functions

virtual bool matched_reader_add(const SubscriptionBuiltinTopicData &info) = 0

Add a matched reader represented by its attributes.

Parameters:

info – Subscription info of the reader being matched.

Returns:

True if added.

virtual bool matched_reader_remove(const GUID_t &reader_guid) = 0

Remove a matched reader.

Parameters:

reader_guid – GUID of the reader to remove.

Returns:

True if removed.

virtual bool matched_reader_is_matched(const GUID_t &reader_guid) = 0

Tells us if a specific Reader is matched against this writer.

Parameters:

reader_guid – GUID of the reader to check.

Returns:

True if it was matched.

virtual void reader_data_filter(IReaderDataFilter *filter) = 0

Set a content filter to perform content filtering on this writer.

This method sets a content filter that will be used to check whether a cache change is relevant for a reader or not.

Parameters:

filter – The content filter to use on this writer. May be nullptr to remove the content filter (i.e. treat all samples as relevant).

virtual const IReaderDataFilter *reader_data_filter() const = 0

Get the content filter used to perform content filtering on this writer.

Returns:

The content filter used on this writer.

virtual bool has_been_fully_delivered(const SequenceNumber_t &seq_num) const = 0

Check if a specific change has been delivered to the transport layer of every matched remote RTPSReader at least once.

Parameters:

seq_num – Sequence number of the change to check.

Returns:

true if delivered. False otherwise.

virtual bool is_acked_by_all(const SequenceNumber_t &seq_num) const = 0

Check if a specific change has been acknowledged by all Readers. Is only useful in reliable Writer. In BE Writers returns false when pending to be sent.

Parameters:

seq_num – Sequence number to check.

Returns:

True if acknowledged by all.

virtual bool wait_for_all_acked(const dds::Duration_t &max_wait) = 0

Waits until all changes were acknowledged or max_wait.

Parameters:

max_wait – Maximum time to wait.

Returns:

True if all were acknowledged.

virtual void update_attributes(const WriterAttributes &att) = 0

Update the Attributes of the Writer.

Parameters:

att – New attributes

virtual WriterListener *get_listener() const = 0

Get listener

Returns:

Listener

virtual bool set_listener(WriterListener *listener) = 0

Set the listener.

Parameters:

listener – Pointer to the listener.

Returns:

True if correctly set.

virtual bool is_async() const = 0

Get the publication mode

Returns:

publication mode

virtual bool get_disable_positive_acks() const = 0

Returns if disable positive ACKs QoS is enabled.

Returns:

Best effort writers always return false. Reliable writers override this method.

virtual bool matched_readers_guids(std::vector<GUID_t> &guids) const = 0

Fills the provided vector with the GUIDs of the matched readers.

Parameters:

guids[out] Vector to be filled with the GUIDs of the matched readers.

Returns:

True if the operation was successful.

20.2.11.2. WriterListener
class WriterListener

Class WriterListener with virtual method so the user can implement callbacks to certain events.

Public Functions

inline virtual void on_writer_matched(RTPSWriter *writer, const MatchingInfo &info)

This method is called when a new Reader is matched with this Writer by the builtin protocols

Parameters:
  • writer – Pointer to the RTPSWriter.

  • info – Matching Information.

inline virtual void on_offered_incompatible_qos(RTPSWriter *writer, eprosima::fastdds::dds::PolicyMask qos)

This method is called when a new Reader is discovered, with a Topic that matches that of a local writer, but with a requested QoS that is incompatible with the one offered by the local writer

Parameters:
  • writer – Pointer to the RTPSWriter.

  • qos – A mask with the bits of all incompatible Qos activated.

inline virtual void on_writer_change_received_by_all(RTPSWriter *writer, CacheChange_t *change)

This method is called when all the readers matched with this Writer acknowledge that a cache change has been received.

Parameters:
inline virtual void on_liveliness_lost(RTPSWriter *writer, const LivelinessLostStatus &status)

Method called when the liveliness of a writer is lost.

Parameters:
  • writer – The writer

  • status – The liveliness lost status

inline virtual void on_reader_discovery(RTPSWriter *writer, ReaderDiscoveryStatus reason, const GUID_t &reader_guid, const SubscriptionBuiltinTopicData *reader_info)

Method called when the discovery information of a reader regarding a writer changes.

Parameters:
  • writer – The writer.

  • reason – The reason motivating this method to be called.

  • reader_guid – The GUID of the reader for which the discovery information changed.

  • reader_info – Discovery information about the reader. Will be nullptr for reason REMOVED_READER.

inline virtual void on_incompatible_type(RTPSWriter *writer)

This method is called when a new Reader is discovered, with a Topic that matches the name of a local writer, but with an incompatible type

Parameters:

writer – Pointer to the RTPSWriter.

20.3. Transport

eProsima Fast DDS Transport Layer API.

20.3.1. Transport Generic Interfaces

20.3.1.1. TransportDescriptorInterface
struct TransportDescriptorInterface

Virtual base class for the data type used to define transport configuration. It acts as a builder for a given transport meaning that it allows to configure the transport, and then a new Transport can be built according to this configuration using its create_transport() factory member function.

  • maxMessageSize: maximum size of a single message in the transport.

  • maxInitialPeersRange: number of channels opened with each initial remote peer.

Subclassed by eprosima::fastdds::rtps::ChainingTransportDescriptor, eprosima::fastdds::rtps::PortBasedTransportDescriptor

Public Functions

inline TransportDescriptorInterface(uint32_t maximumMessageSize, uint32_t maximumInitialPeersRange)

Constructor.

inline TransportDescriptorInterface(const TransportDescriptorInterface &t)

Copy constructor.

inline TransportDescriptorInterface &operator=(const TransportDescriptorInterface &t)

Copy assignment.

virtual ~TransportDescriptorInterface() = default

Destructor.

virtual TransportInterface *create_transport() const = 0

Factory method pattern. It will create and return a TransportInterface corresponding to this descriptor. This provides an interface to the NetworkFactory to create the transports without the need to know about their type

virtual uint32_t min_send_buffer_size() const = 0

Returns the minimum size required for a send operation.

inline virtual uint32_t max_message_size() const

Returns the maximum size expected for received messages.

inline virtual uint32_t max_initial_peers_range() const

Returns the maximum number of opened channels for each initial remote peer (maximum number of guessed initial peers to try to connect)

inline bool operator==(const TransportDescriptorInterface &t) const

Comparison operator.

inline void lock()

Lock internal mutex (for Fast-DDS internal use)

inline void unlock()

Unlock internal mutex (for Fast-DDS internal use)

Public Members

uint32_t maxMessageSize

Maximum size of a single message in the transport.

uint32_t maxInitialPeersRange

Number of channels opened with each initial remote peer.

20.3.1.2. TransportInterface
class TransportInterface

Interface against which to implement a transport layer, decoupled from Fast DDS internals. TransportInterface expects the user to implement a logical equivalence between Locators and protocol-specific “channels”. This equivalence can be narrowing: For instance in UDP/IP, a port would take the role of channel, and several different locators can map to the same port, and hence the same channel.

Subclassed by eprosima::fastdds::rtps::ChainingTransport

Public Functions

virtual ~TransportInterface() = default

Aside from the API defined here, an user-defined Transport must define a descriptor data type and a constructor that expects a constant reference to such descriptor. e.g:

class MyTransport: public: typedef struct { … } MyTransportDescriptor; MyTransport(const MyTransportDescriptor&); …

TransportInterface(const TransportInterface &t) = delete

Copy constructor.

TransportInterface &operator=(const TransportInterface &t) = delete

Copy assignment.

TransportInterface(TransportInterface &&t) = delete

Move constructor.

TransportInterface &operator=(TransportInterface &&t) = delete

Move assignment.

virtual bool init(const fastdds::rtps::PropertyPolicy *properties = nullptr, const uint32_t &max_msg_size_no_frag = 0) = 0

Initialize this transport. This method will prepare all the internals of the transport.

Parameters:
  • properties – Optional policy to specify additional parameters of the created transport.

  • max_msg_size_no_frag – Optional maximum message size to avoid 65500 KB fragmentation limit.

Returns:

True when the transport was correctly initialized.

virtual bool IsInputChannelOpen(const Locator&) const = 0

Must report whether the input channel associated to this locator is open. Channels must either be fully closed or fully open, so that “open” and “close” operations are whole and definitive.

virtual bool IsLocatorSupported(const Locator&) const = 0

Must report whether the given locator is supported by this transport (typically inspecting its “kind” value).

virtual bool is_locator_allowed(const Locator&) const = 0

Must report whether the given locator is allowed by this transport.

virtual bool is_locator_reachable(const Locator_t &locator) = 0

Must report whether the given locator is reachable by this transport.

Parameters:

locator[in] Locator for which the reachability is checked.

Returns:

true if the input locator is reachable by this transport, false otherwise.

virtual Locator RemoteToMainLocal(const Locator &remote) const = 0

Returns the locator describing the main (most general) channel that can write to the provided remote locator.

inline virtual bool transform_remote_locator(const Locator &remote_locator, Locator &result_locator) const

Transforms a remote locator into a locator optimized for local communications.

If the remote locator corresponds to one of the local interfaces, it is converted to the corresponding local address.

Parameters:
  • remote_locator[in] Locator to be converted.

  • result_locator[out] Converted locator.

Returns:

false if the input locator is not supported/allowed by this transport, true otherwise.

virtual bool OpenOutputChannel(SendResourceList &sender_resource_list, const Locator&) = 0

Must open the channel that maps to/from the given locator. This method must allocate, reserve and mark any resources that are needed for said channel.

virtual bool OpenOutputChannels(SendResourceList &sender_resource_list, const fastdds::rtps::LocatorSelectorEntry &locator_selector_entry)

Must open the channel that maps to/from the given locator selector entry. This method must allocate, reserve and mark any resources that are needed for said channel.

Parameters:
  • sender_resource_list – Participant’s send resource list.

  • locator_selector_entry – Locator selector entry with the remote entity locators.

Returns:

true if the channel was correctly opened or if finding an already opened one.

virtual void CloseOutputChannels(SendResourceList &sender_resource_list, const fastdds::rtps::LocatorSelectorEntry &locator_selector_entry)

Close the channel that maps to/from the given locator selector entry.

Parameters:
  • sender_resource_list – Participant’s send resource list.

  • locator_selector_entry – Locator selector entry with the remote entity locators.

virtual bool OpenInputChannel(const Locator&, TransportReceiverInterface*, uint32_t) = 0

Opens an input channel to receive incoming connections. If there is an existing channel it registers the receiver interface.

virtual bool CloseInputChannel(const Locator&) = 0

Must close the channel that maps to/from the given locator. IMPORTANT: It MUST be safe to call this method even during a Receive operation on another thread. You must implement any necessary mutual exclusion and timeout mechanisms to make sure the channel can be closed without damage.

virtual bool DoInputLocatorsMatch(const Locator&, const Locator&) const = 0

Must report whether two locators map to the same internal channel.

virtual LocatorList NormalizeLocator(const Locator &locator) = 0

Performs locator normalization (assign valid IP if not defined by user)

virtual void select_locators(fastdds::rtps::LocatorSelector &selector) const = 0

Performs the locator selection algorithm for this transport.

It basically consists of the following steps

  • selector.transport_starts is called

  • transport handles the selection state of each locator

  • if a locator from an entry is selected, selector.select is called for that entry

Parameters:

selector[inout] Locator selector.

virtual bool is_local_locator(const Locator &locator) const = 0

Must report whether the given locator is from the local host.

virtual TransportDescriptorInterface *get_configuration() = 0

Return the transport configuration (Transport Descriptor)

virtual void AddDefaultOutputLocator(LocatorList &defaultList) = 0

Add default output locator to the locator list.

virtual bool getDefaultMetatrafficMulticastLocators(LocatorList &locators, uint32_t metatraffic_multicast_port) const = 0

Add metatraffic multicast locator with the given port.

virtual bool getDefaultMetatrafficUnicastLocators(LocatorList &locators, uint32_t metatraffic_unicast_port) const = 0

Add metatraffic unicast locator with the given port.

virtual bool getDefaultUnicastLocators(LocatorList &locators, uint32_t unicast_port) const = 0

Add unicast locator with the given port.

virtual bool fillMetatrafficMulticastLocator(Locator &locator, uint32_t metatraffic_multicast_port) const = 0

Assign port to the given metatraffic multicast locator if not already defined.

virtual bool fillMetatrafficUnicastLocator(Locator &locator, uint32_t metatraffic_unicast_port) const = 0

Assign port to the given metatraffic unicast locator if not already defined.

virtual bool configureInitialPeerLocator(Locator &locator, const fastdds::rtps::PortParameters &port_params, uint32_t domainId, LocatorList &list) const = 0

Configure the initial peer locators list.

virtual bool fillUnicastLocator(Locator &locator, uint32_t well_known_port) const = 0

Assign port to the given unicast locator if not already defined.

virtual uint32_t max_recv_buffer_size() const = 0
Returns:

The maximum datagram size for reception supported by the transport

inline virtual void shutdown()

Shutdown method to close the connections of the transports.

inline virtual void update_network_interfaces()

Update network interfaces.

inline int32_t kind() const

Return the transport kind.

inline virtual bool transform_remote_locator(const Locator &remote_locator, Locator &result_locator, bool allowed_remote_localhost, bool allowed_local_localhost) const

Transforms a remote locator into a locator optimized for local communications.

If the remote locator corresponds to one of the local interfaces, it is converted to the corresponding local address if allowed by both local and remote transports.

Parameters:
  • remote_locator[in] Locator to be converted.

  • result_locator[out] Converted locator.

  • allowed_remote_localhost[in] Whether localhost is allowed (and hence used) in the remote transport.

  • allowed_local_localhost[in] Whether localhost is allowed locally (by this or other transport).

Returns:

false if the input locator is not supported/allowed by this transport, true otherwise.

inline virtual bool is_localhost_allowed() const

Must report whether localhost locator is allowed.

inline virtual NetmaskFilterInfo netmask_filter_info() const

Returns netmask filter information (transport’s netmask filter kind and allowlist)

constexpr uint32_t eprosima::fastdds::rtps::s_maximumMessageSize = 65500

Default maximum message size.

constexpr uint32_t eprosima::fastdds::rtps::s_maximumInitialPeersRange = 4

Default maximum initial peers range.

static const std::string eprosima::fastdds::rtps::s_IPv4AddressAny = "0.0.0.0"

Default IPv4 address.

static const std::string eprosima::fastdds::rtps::s_IPv6AddressAny = "::"

Default IPv6 address.

using eprosima::fastdds::rtps::SendResourceList = std::vector<std::unique_ptr<fastdds::rtps::SenderResource>>
20.3.1.3. TransportReceiverInterface
class TransportReceiverInterface

Interface against which to implement a data receiver, decoupled from transport internals.

Public Functions

virtual ~TransportReceiverInterface() = default

Destructor.

virtual void OnDataReceived(const fastdds::rtps::octet *data, const uint32_t size, const Locator &local_locator, const Locator &remote_locator) = 0

Method to be called by the transport when receiving data.

Parameters:
  • data – Pointer to the received data.

  • size – Number of bytes received.

  • local_locator – Locator identifying the local endpoint.

  • remote_locator – Locator identifying the remote endpoint.

20.3.1.4. PortBasedTransportDescriptor
class PortBasedTransportDescriptor : public eprosima::fastdds::rtps::TransportDescriptorInterface

Base class for all port based transport descriptors

This class provides a common thread settings configuration for all port based transport descriptor implementations

Subclassed by eprosima::fastdds::rtps::SharedMemTransportDescriptor, eprosima::fastdds::rtps::SocketTransportDescriptor

Public Functions

PortBasedTransportDescriptor(uint32_t maximumMessageSize, uint32_t maximumInitialPeersRange)

Constructor.

PortBasedTransportDescriptor(const PortBasedTransportDescriptor &t) = default

Copy constructor.

PortBasedTransportDescriptor &operator=(const PortBasedTransportDescriptor &t) = default

Copy assignment.

virtual ~PortBasedTransportDescriptor() = default

Destructor.

bool operator==(const PortBasedTransportDescriptor &t) const

Comparison operator.

virtual const ThreadSettings &get_thread_config_for_port(uint32_t port) const

Get the ThreadSettings for a specific port.

This function first looks for the port-specific ThreadSettings in the user-configured reception threads map, i.e. the collection of ThreadSettings returned by reception_threads(). If the ThreadSettings are found within said map, then get_thread_config_for_port() returns them; else it returns the default reception thread settings, i.e. the ThreadSettings returned by default_reception_threads().

Warning

This function will return the default reception thread ThreadSettings when called with a non-default, non-user-configured port.

Parameters:

port – The port to which the returned ThreadSetting apply.

Returns:

The ThreadSettings for the given port.

const ThreadSettings &default_reception_threads() const

Returns the ThreadSettings for the default reception threads.

virtual void default_reception_threads(const ThreadSettings &default_reception_threads)

Set the ThreadSettings for the default reception threads.

const ReceptionThreadsConfigMap &reception_threads() const

Returns the ThreadSettings for the user-configured reception threads.

virtual bool reception_threads(const ReceptionThreadsConfigMap &reception_threads)

Set the ThreadSettings for the user-configured reception threads.

20.3.1.5. SocketTransportDescriptor
struct SocketTransportDescriptor : public eprosima::fastdds::rtps::PortBasedTransportDescriptor

Virtual base class for the data type used to define configuration of transports using sockets.

  • sendBufferSize: size of the sending buffer of the socket (in octets).

  • receiveBufferSize: size of the receiving buffer of the socket (in octets).

  • interfaceWhiteList: list of allowed interfaces.

  • TTL: time to live, in number of hops.

Subclassed by eprosima::fastdds::rtps::TCPTransportDescriptor, eprosima::fastdds::rtps::test_UDPv4TransportDescriptor, eprosima::fastdds::rtps::UDPTransportDescriptor

Public Functions

inline SocketTransportDescriptor(uint32_t maximumMessageSize, uint32_t maximumInitialPeersRange)

Constructor.

SocketTransportDescriptor(const SocketTransportDescriptor &t) = default

Copy constructor.

SocketTransportDescriptor &operator=(const SocketTransportDescriptor &t) = default

Copy assignment.

virtual ~SocketTransportDescriptor() = default

Destructor.

inline virtual uint32_t min_send_buffer_size() const override

Returns the minimum size required for a send operation.

inline bool operator==(const SocketTransportDescriptor &t) const

Comparison operator.

Public Members

uint32_t sendBufferSize

Length of the send buffer.

uint32_t receiveBufferSize

Length of the receive buffer.

std::vector<std::string> interfaceWhiteList

Allowed interfaces in an IP or device name string format.

NetmaskFilterKind netmask_filter

Transport’s netmask filter configuration.

std::vector<AllowedNetworkInterface> interface_allowlist

Allowed interfaces in an IP or device name string format, each with a specific netmask filter configuration.

std::vector<BlockedNetworkInterface> interface_blocklist

Blocked interfaces in an IP or device name string format.

uint8_t TTL

Specified time to live (8bit - 255 max TTL)

constexpr uint8_t eprosima::fastdds::rtps::s_defaultTTL = 1

Default time to live (TTL)

20.3.2. Chaining of transports

20.3.2.1. ChainingTransportDescriptor
struct ChainingTransportDescriptor : public eprosima::fastdds::rtps::TransportDescriptorInterface

Base class for the descriptors of chaining transports. A chaining transport allows for the manipulation of data before sending or after receiving from another transport.

Transport configuration:

  • low_level_descriptor: Descriptor for lower level transport.

Public Functions

inline virtual uint32_t min_send_buffer_size() const override

Returns the minimum size required for a send operation.

inline virtual uint32_t max_message_size() const override

Returns the maximum size expected for received messages.

Public Members

std::shared_ptr<TransportDescriptorInterface> low_level_descriptor

Descriptor for lower level transport.

20.3.2.2. ChainingTransport
class ChainingTransport : public eprosima::fastdds::rtps::TransportInterface

This is the base class for chaining adapter transports.

  • Directly proxies all operations except Send and Receive

  • Has a pointer to the low level transport

Public Functions

inline ChainingTransport(const ChainingTransportDescriptor &t)

Constructor.

virtual ~ChainingTransport() = default

Destructor.

inline virtual bool init(const fastdds::rtps::PropertyPolicy *properties = nullptr, const uint32_t &max_msg_size_no_frag = 0) override

Initialize the low-level transport.

This method will prepare all the internals of the transport.

Parameters:
  • properties – Optional policy to specify additional parameters of the created transport.

  • max_msg_size_no_frag – Optional maximum message size to avoid 65500 KB fragmentation limit.

Returns:

True when the transport was correctly initialized.

inline virtual bool IsInputChannelOpen(const fastdds::rtps::Locator_t &loc) const override

Call the low-level transport IsInputChannelOpen().

Must report whether the input channel associated to this locator is open. Channels must either be fully closed or fully open, so that “open” and “close” operations are whole and definitive.

inline virtual bool IsLocatorSupported(const fastdds::rtps::Locator_t &loc) const override

Call the low-level transport IsLocatorSupported().

Must report whether the given locator is supported by this transport (typically inspecting its “kind” value).

inline virtual fastdds::rtps::Locator_t RemoteToMainLocal(const fastdds::rtps::Locator_t &loc) const override

Call the low-level transport RemoteToMainLocal().

Returns the locator describing the main (most general) channel that can write to the provided remote locator.

virtual bool OpenInputChannel(const fastdds::rtps::Locator_t &loc, TransportReceiverInterface *receiver_interface, uint32_t max_message_size) override

Call the low-level transport OpenInputChannel().

Opens an input channel to receive incoming connections. If there is an existing channel it registers the receiver interface.

virtual bool OpenOutputChannel(SendResourceList &sender_resource_list, const fastdds::rtps::Locator_t &loc) override

Call the low-level transport OpenOutputChannel().

Must open the channel that maps to/from the given locator. This method must allocate, reserve and mark any resources that are needed for said channel.

inline virtual bool CloseInputChannel(const fastdds::rtps::Locator_t &loc) override

Call the low-level transport CloseInputChannel().

Must close the channel that maps to/from the given locator. IMPORTANT: It MUST be safe to call this method even during a Receive operation on another thread. You must implement any necessary mutual exclusion and timeout mechanisms to make sure the channel can be closed without damage.

inline virtual fastdds::rtps::LocatorList_t NormalizeLocator(const fastdds::rtps::Locator_t &locator) override

Call the low-level transport NormalizeLocator().

Performs locator normalization (assign valid IP if not defined by user)

inline virtual bool is_local_locator(const fastdds::rtps::Locator_t &locator) const override

Call the low-level transport is_local_locator().

Must report whether the given locator is from the local host

inline virtual bool is_localhost_allowed() const override

Call the low-level transport is_localhost_allowed().

Must report whether localhost locator is allowed

inline virtual NetmaskFilterInfo netmask_filter_info() const override

Call the low-level transport netmask_filter_info().

Returns netmask filter information (transport’s netmask filter kind and allowlist)

inline virtual bool DoInputLocatorsMatch(const fastdds::rtps::Locator_t &locator_1, const fastdds::rtps::Locator_t &locator_2) const override

Call the low-level transport DoInputLocatorsMatch().

Must report whether two locators map to the same internal channel.

inline virtual void select_locators(fastdds::rtps::LocatorSelector &selector) const override

Call the low-level transport select_locators().

Performs the locator selection algorithm for this transport.

inline virtual void AddDefaultOutputLocator(fastdds::rtps::LocatorList_t &defaultList) override

Call the low-level transport AddDefaultOutputLocator().

Add default output locator to the locator list

inline virtual bool getDefaultMetatrafficMulticastLocators(fastdds::rtps::LocatorList_t &locators, uint32_t metatraffic_multicast_port) const override

Call the low-level transport getDefaultMetatrafficMulticastLocators().

Add metatraffic multicast locator with the given port

inline virtual bool getDefaultMetatrafficUnicastLocators(fastdds::rtps::LocatorList_t &locators, uint32_t metatraffic_unicast_port) const override

Call the low-level transport getDefaultMetatrafficUnicastLocators().

Add metatraffic unicast locator with the given port

inline virtual bool getDefaultUnicastLocators(fastdds::rtps::LocatorList_t &locators, uint32_t unicast_port) const override

Call the low-level transport getDefaultUnicastLocators().

Add unicast locator with the given port

inline virtual bool fillMetatrafficMulticastLocator(fastdds::rtps::Locator_t &locator, uint32_t metatraffic_multicast_port) const override

Call the low-level transport fillMetatrafficMulticastLocator().

Assign port to the given metatraffic multicast locator if not already defined

inline virtual bool fillMetatrafficUnicastLocator(fastdds::rtps::Locator_t &locator, uint32_t metatraffic_unicast_port) const override

Call the low-level transport fillMetatrafficUnicastLocator().

Assign port to the given metatraffic unicast locator if not already defined

inline virtual bool configureInitialPeerLocator(fastdds::rtps::Locator_t &locator, const fastdds::rtps::PortParameters &port_params, uint32_t domainId, fastdds::rtps::LocatorList_t &list) const override

Call the low-level transport configureInitialPeerLocator().

Configure the initial peer locators list

inline virtual bool fillUnicastLocator(fastdds::rtps::Locator_t &locator, uint32_t well_known_port) const override

Call the low-level transport fillUnicastLocator().

Assign port to the given unicast locator if not already defined

inline virtual bool transform_remote_locator(const fastdds::rtps::Locator_t &remote_locator, fastdds::rtps::Locator_t &result_locator) const override

Call the low-level transport transform_remote_locator(). Transforms a remote locator into a locator optimized for local communications.

inline virtual uint32_t max_recv_buffer_size() const override

Call the low-level transport max_recv_buffer_size().

Returns:

The maximum datagram size for reception supported by the transport

virtual bool send(fastdds::rtps::SenderResource *low_sender_resource, const std::vector<NetworkBuffer> &buffers, uint32_t total_bytes, fastdds::rtps::LocatorsIterator *destination_locators_begin, fastdds::rtps::LocatorsIterator *destination_locators_end, const std::chrono::steady_clock::time_point &timeout) = 0

Blocking Send through the specified channel. It may perform operations on the output buffer. At the end the function must call to the low-level transport’s send() function.

// Example of calling the low-level transport `send()` function.
return low_sender_resource->send(buffers, total_bytes, destination_locators_begin,
            destination_locators_end, timeout);

Parameters:
  • low_sender_resource – SenderResource generated by the lower transport.

  • buffers – Vector of buffers to send.

  • total_bytes – Length of all buffers to be sent. Will be used as a boundary for the previous parameter. It must not exceed the sendBufferSize fed to this class during construction.

  • destination_locators_begin – First iterator of the list of Locators describing the remote destinations we’re sending to.

  • destination_locators_end – End iterator of the list of Locators describing the remote destinations we’re sending to.

  • timeout – Maximum blocking time.

virtual void receive(TransportReceiverInterface *next_receiver, const fastdds::rtps::octet *receive_buffer, uint32_t receive_buffer_size, const fastdds::rtps::Locator_t &local_locator, const fastdds::rtps::Locator_t &remote_locator) = 0

Blocking Receive from the specified channel.

It may perform operations on the input buffer. At the end the function must call to the next_receiver’s OnDataReceived function.

// Example of calling the `next_receiver`'s `OnDataReceived` function.
next_receiver->OnDataReceived(receive_buffer, receive_buffer_size, local_locator, remote_locator);

Parameters:
  • next_receiver – Next resource receiver to be called.

  • receive_buffer – vector with enough capacity (not size) to accommodate a full receive buffer. That capacity must not be less than the receiveBufferSize supplied to this class during construction.

  • receive_buffer_size – Size of the raw data. It will be used as bounds check for the previous argument. It must not exceed the receiveBufferSize fed to this class during construction.

  • local_locator – Locator mapping to the local channel we’re listening to.

  • remote_locator[out] Locator describing the remote destination we received a packet from.

inline virtual void update_network_interfaces() override

Update network interfaces.

inline virtual bool transform_remote_locator(const fastdds::rtps::Locator_t &remote_locator, fastdds::rtps::Locator_t &result_locator, bool allowed_remote_localhost, bool allowed_local_localhost) const override

Call the low-level transport transform_remote_locator(). Transforms a remote locator into a locator optimized for local communications, if allowed by both local and remote transports.

inline virtual bool is_locator_allowed(const fastdds::rtps::Locator_t &locator) const override

Call the low-level transport is_locator_allowed().

Must report whether the given locator is allowed by this transport.

inline virtual bool is_locator_reachable(const fastdds::rtps::Locator_t &locator) override

Call the low-level transport is_locator_reachable().

Must report whether the given locator is reachable by this transport.

20.3.3. UDP Transport

20.3.3.1. UDPTransportDescriptor
struct UDPTransportDescriptor : public eprosima::fastdds::rtps::SocketTransportDescriptor

UDP Transport configuration

  • m_output_udp_socket: source port to use for outgoing datagrams.

  • non_blocking_send: do not block on send operations. When it is set to true, send operations will return immediately if the buffer is full, but no error will be returned to the upper layer. This means that the application will behave as if the datagram is sent and lost.

Subclassed by eprosima::fastdds::rtps::UDPv4TransportDescriptor, eprosima::fastdds::rtps::UDPv6TransportDescriptor

Public Functions

virtual ~UDPTransportDescriptor() = default

Destructor.

UDPTransportDescriptor()

Constructor.

UDPTransportDescriptor(const UDPTransportDescriptor &t) = default

Copy constructor.

UDPTransportDescriptor &operator=(const UDPTransportDescriptor &t) = default

Copy assignment.

bool operator==(const UDPTransportDescriptor &t) const

Comparison operator.

Public Members

uint16_t m_output_udp_socket

Source port to use for outgoing datagrams.

bool non_blocking_send = false

Whether to use non-blocking calls to send_to().

When set to true, calls to send_to() will return immediately if the buffer is full, but no error will be returned to the upper layer. This means that the application will behave as if the datagram is sent but lost (i.e. throughput may be reduced). This value is specially useful on high-frequency best-effort writers.

When set to false, calls to send_to() will block until the network buffer has space for the datagram. This may hinder performance on high-frequency writers.

20.3.3.2. UDPv4TransportDescriptor
struct UDPv4TransportDescriptor : public eprosima::fastdds::rtps::UDPTransportDescriptor

UDPv4 Transport configuration The kind value for UDPv4TransportDescriptor is given by eprosima::fastdds::rtps::LOCATOR_KIND_UDPv4.

Public Functions

virtual ~UDPv4TransportDescriptor() = default

Destructor.

virtual TransportInterface *create_transport() const override

Factory method pattern. It will create and return a TransportInterface corresponding to this descriptor. This provides an interface to the NetworkFactory to create the transports without the need to know about their type

UDPv4TransportDescriptor()

Constructor.

UDPv4TransportDescriptor(const UDPv4TransportDescriptor &t) = default

Copy constructor.

UDPv4TransportDescriptor &operator=(const UDPv4TransportDescriptor &t) = default

Copy assignment.

20.3.3.3. UDPv6TransportDescriptor
struct UDPv6TransportDescriptor : public eprosima::fastdds::rtps::UDPTransportDescriptor

UDPv6 Transport configuration The kind value for UDPv6TransportDescriptor is given by eprosima::fastdds::rtps::LOCATOR_KIND_UDPv6.

Public Functions

virtual ~UDPv6TransportDescriptor() = default

Destructor.

virtual TransportInterface *create_transport() const override

Factory method pattern. It will create and return a TransportInterface corresponding to this descriptor. This provides an interface to the NetworkFactory to create the transports without the need to know about their type

UDPv6TransportDescriptor()

Constructor.

UDPv6TransportDescriptor(const UDPv6TransportDescriptor &t) = default

Copy constructor.

UDPv6TransportDescriptor &operator=(const UDPv6TransportDescriptor &t) = default

Copy assignment.

20.3.4. TCP Transport

20.3.4.1. TCPTransportDescriptor
struct TCPTransportDescriptor : public eprosima::fastdds::rtps::SocketTransportDescriptor

TCP Transport configuration

  • listening_ports: list of ports to listen as server.

  • keep_alive_frequency_ms: frequency of RTCP keep alive requests (in ms).

  • keep_alive_timeout_ms: time since sending the last keep alive request to consider a connection as broken (in ms).

  • max_logical_port: maximum number of logical ports to try during RTCP negotiation.

  • logical_port_range: maximum number of logical ports per request to try during RTCP negotiation.

  • logical_port_increment: increment between logical ports to try during RTCP negotiation.

  • enable_tcp_nodelay: enables the TCP_NODELAY socket option.

  • calculate_crc: true to calculate and send CRC on message headers.

  • check_crc: true to check the CRC of incoming message headers.

  • apply_security: true to use TLS (Transport Layer Security).

  • tls_config: Configuration for TLS.

  • non_blocking_send: do not block on send operations. When it is set to true, send operations will return immediately if the buffer might get full, but no error will be returned to the upper layer. This means that the application will behave as if the datagram is sent and lost.

  • tcp_negotiation_timeout: time to wait for logical port negotiation (in ms).

Subclassed by eprosima::fastdds::rtps::TCPv4TransportDescriptor, eprosima::fastdds::rtps::TCPv6TransportDescriptor

Public Functions

inline void add_listener_port(uint16_t port)

Add listener port to the listening_ports list.

TCPTransportDescriptor()

Constructor.

TCPTransportDescriptor(const TCPTransportDescriptor &t)

Copy constructor.

TCPTransportDescriptor &operator=(const TCPTransportDescriptor &t)

Copy assignment.

virtual ~TCPTransportDescriptor() = default

Destructor.

bool operator==(const TCPTransportDescriptor &t) const

Comparison operator.

Public Members

std::vector<uint16_t> listening_ports

List of ports to listen as server.

uint32_t keep_alive_frequency_ms

Frequency of RTCP keep alive requests (ms)

uint32_t keep_alive_timeout_ms

Time since sending the last keep alive request to consider a connection as broken (ms)

uint16_t max_logical_port

Maximum number of logical ports to try during RTCP negotiation.

uint16_t logical_port_range

Maximum number of logical ports per request to try during RTCP negotiation.

uint16_t logical_port_increment

Increment between logical ports to try during RTCP negotiation.

uint32_t tcp_negotiation_timeout

Time to wait for logical port negotiation (ms). If a logical port is under negotiation, it waits for the negotiation to finish up to this timeout before trying to send a message to that port. Zero value means no waiting (default).

bool enable_tcp_nodelay

Enables the TCP_NODELAY socket option.

bool calculate_crc

Enables the calculation and sending of CRC on message headers.

bool check_crc

Enables checking the CRC of incoming message headers.

bool apply_security

Enables the use of TLS (Transport Layer Security)

TLSConfig tls_config

Configuration of the TLS (Transport Layer Security)

ThreadSettings keep_alive_thread

Thread settings for keep alive thread.

ThreadSettings accept_thread

Thread settings for the accept connections thread.

bool non_blocking_send

Whether to use non-blocking calls to send().

When set to true, calls to send() will return immediately if the send buffer might get full. This may happen when receive buffer on reader’s side is full. No error will be returned to the upper layer. This means that the application will behave as if the datagram is sent but lost (i.e. throughput may be reduced). This value is specially useful on high-frequency writers.

When set to false, which is the default, calls to send() will block until the send buffer has space for the datagram. This may cause application lock.

struct TLSConfig

TLS Configuration

  • password: password of the private_key_file or rsa_private_key_file.

  • private_key_file: path to the private key certificate file.

  • rsa_private_key_file: path to the private key RSA certificate file.

  • cert_chain_file: path to the public certificate chain file.

  • tmp_dh_file: path to the Diffie-Hellman parameters file.

  • verify_file: path to the CA (Certification-Authority) file.

  • verify_mode: establishes the verification mode mask.

  • options: establishes the SSL Context options mask.

  • verify_paths: paths where the system will look for verification files.

  • default_verify_path: look for verification files on the default paths.

  • handshake_role: role that the transport will take on handshaking.

  • server_name: server name or host name required in case Server Name Indication (SNI) is used.

Public Types

enum TLSOptions

Supported TLS features. Several options can be combined in the same TransportDescriptor using the add_option() member function.

  • DEFAULT_WORKAROUNDS: implement various bug workarounds.

  • NO_COMPRESSION: disable compression.

  • NO_SSLV2: disable SSL v2.

  • NO_SSLV3: disable SSL v3.

  • NO_TLSV1: disable TLS v1.

  • NO_TLSV1_1: disable TLS v1.1.

  • NO_TLSV1_2: disable TLS v1.2.

  • NO_TLSV1_3: disable TLS v1.3.

  • SINGLE_DH_USE: always create a new key using Diffie-Hellman parameters.

Values:

enumerator NONE
enumerator DEFAULT_WORKAROUNDS
enumerator NO_COMPRESSION
enumerator NO_SSLV2
enumerator NO_SSLV3
enumerator NO_TLSV1
enumerator NO_TLSV1_1
enumerator NO_TLSV1_2
enumerator NO_TLSV1_3
enumerator SINGLE_DH_USE
enum TLSVerifyMode

Peer node verification options. Several verification options can be combined in the same TransportDescriptor using the add_verify_mode() member function.

  • VERIFY_NONE: perform no verification.

  • VERIFY_PEER: perform verification of the peer.

  • VERIFY_FAIL_IF_NO_PEER_CERT: fail verification if the peer has no certificate. Ignored unless VERIFY_PEER is also set.

  • VERIFY_CLIENT_ONCE: do not request client certificate on renegotiation. Ignored unless VERIFY_PEER is also set.

Values:

enumerator UNUSED
enumerator VERIFY_NONE
enumerator VERIFY_PEER
enumerator VERIFY_FAIL_IF_NO_PEER_CERT
enumerator VERIFY_CLIENT_ONCE
enum TLSHandShakeRole

Role that the transport will take on handshaking.

  • DEFAULT: configured as client if connector, and as server if acceptor.

  • CLIENT: configured as client.

  • SERVER: configured as server.

Values:

enumerator DEFAULT
enumerator CLIENT
enumerator SERVER

Public Functions

inline void add_verify_mode(const TLSVerifyMode verify)

Add verification modes to the verification mode mask.

inline bool get_verify_mode(const TLSVerifyMode verify) const

Get the verification mode mask.

inline void add_option(const TLSOptions option)

Add TLS features to the SSL Context options mask.

inline bool get_option(const TLSOptions option) const

Get the SSL Context options mask.

inline bool operator==(const TLSConfig &t) const

Comparison operator.

Public Members

std::string password

Password of the private_key_file or rsa_private_key_file.

uint32_t options = TLSOptions::NONE

SSL context options mask.

std::string cert_chain_file

Path to the public certificate chain file.

std::string private_key_file

Path to the private key certificate file.

std::string tmp_dh_file

Path to the Diffie-Hellman parameters file.

std::string verify_file

Path to the CA (Certification-Authority) file.

uint8_t verify_mode = TLSVerifyMode::UNUSED

Verification mode mask.

std::vector<std::string> verify_paths

Paths where the system will look for verification files.

bool default_verify_path = false

Look for verification files on the default paths.

int32_t verify_depth = -1

Maximum allowed depth for verifying intermediate certificates. Do not override.

std::string rsa_private_key_file

Path to the private key RSA certificate file.

TLSHandShakeRole handshake_role = TLSHandShakeRole::DEFAULT

Role that the transport will take on handshaking.

std::string server_name

Server name or host name required in case Server Name Indication (SNI) is used.

20.3.4.2. TCPv4TransportDescriptor
struct TCPv4TransportDescriptor : public eprosima::fastdds::rtps::TCPTransportDescriptor

TCPv4 Transport configuration. The kind value for TCPv4TransportDescriptor is given by eprosima::fastdds::rtps::LOCATOR_KIND_TCPv4.

  • wan_addr: Public IP address. Peers on a different LAN will use this IP for communications with this host.

Public Functions

virtual ~TCPv4TransportDescriptor() = default

Destructor.

virtual TransportInterface *create_transport() const override

Factory method pattern. It will create and return a TransportInterface corresponding to this descriptor. This provides an interface to the NetworkFactory to create the transports without the need to know about their type

inline void set_WAN_address(fastdds::rtps::octet o1, fastdds::rtps::octet o2, fastdds::rtps::octet o3, fastdds::rtps::octet o4)

Set the public IP address.

inline void set_WAN_address(const std::string &in_address)

Set the public IP address.

inline std::string get_WAN_address()

Get the public IP address.

TCPv4TransportDescriptor()

Constructor.

TCPv4TransportDescriptor(const TCPv4TransportDescriptor &t)

Copy constructor.

TCPv4TransportDescriptor &operator=(const TCPv4TransportDescriptor &t)

Copy assignment.

bool operator==(const TCPv4TransportDescriptor &t) const

Comparison operator.

Public Members

fastdds::rtps::octet wan_addr[4]

Public IP address.

20.3.4.3. TCPv6TransportDescriptor
struct TCPv6TransportDescriptor : public eprosima::fastdds::rtps::TCPTransportDescriptor

TCPv6 Transport configuration The kind value for TCPv6TransportDescriptor is given by eprosima::fastdds::rtps::LOCATOR_KIND_TCPv6.

Public Functions

virtual ~TCPv6TransportDescriptor() = default

Destructor.

virtual TransportInterface *create_transport() const override

Factory method pattern. It will create and return a TransportInterface corresponding to this descriptor. This provides an interface to the NetworkFactory to create the transports without the need to know about their type

TCPv6TransportDescriptor()

Constructor.

TCPv6TransportDescriptor(const TCPv6TransportDescriptor &t)

Copy constructor.

TCPv6TransportDescriptor &operator=(const TCPv6TransportDescriptor &t) = default

Copy assignment.

bool operator==(const TCPv6TransportDescriptor &t) const

Comparison operator.

20.3.5. Shared Memory Transport

20.3.5.1. SharedMemTransportDescriptor
struct SharedMemTransportDescriptor : public eprosima::fastdds::rtps::PortBasedTransportDescriptor

Shared memory transport configuration. The kind is given by eprosima::fastdds::rtps::LOCATOR_KIND_SHM.

  • segment_size_: size of the shared memory segment (in octets).

  • port_queue_capacity_: size of the listening port (in messages).

  • healthy_check_timeout_ms_: timeout for the health check of ports (ms).

  • rtps_dump_file_: full path of the protocol dump file.

Subclassed by eprosima::fastdds::rtps::test_SharedMemTransportDescriptor

Public Functions

virtual ~SharedMemTransportDescriptor() = default

Destructor.

virtual TransportInterface *create_transport() const override

Factory method pattern. It will create and return a TransportInterface corresponding to this descriptor. This provides an interface to the NetworkFactory to create the transports without the need to know about their type

inline virtual uint32_t min_send_buffer_size() const override

Minimum size of the send buffer.

SharedMemTransportDescriptor()

Constructor.

SharedMemTransportDescriptor(const SharedMemTransportDescriptor &t) = default

Copy constructor.

SharedMemTransportDescriptor &operator=(const SharedMemTransportDescriptor &t) = default

Copy assignment.

inline uint32_t segment_size() const

Return the size of the shared memory segment.

inline void segment_size(uint32_t segment_size)

Set the size of the shared memory segment.

inline virtual uint32_t max_message_size() const override

Return the maximum size of a single message in the transport (in octets)

inline void max_message_size(uint32_t max_message_size)

Set the maximum size of a single message in the transport (in octets)

inline uint32_t port_queue_capacity() const

Return the size of the listening port (in messages)

inline void port_queue_capacity(uint32_t port_queue_capacity)

Set the size of the listening port (in messages)

inline uint32_t healthy_check_timeout_ms() const

Return the timeout for the health check of ports (ms)

inline void healthy_check_timeout_ms(uint32_t healthy_check_timeout_ms)

Set the timeout for the health check of ports (ms)

inline std::string rtps_dump_file() const

Return the full path of the protocol dump file.

inline void rtps_dump_file(const std::string &rtps_dump_file)

Set the full path of the protocol dump file.

inline ThreadSettings dump_thread() const

Return the thread settings for the transport dump thread.

inline void dump_thread(const ThreadSettings &dump_thread)

Set the thread settings for the transport dump thread.

bool operator==(const SharedMemTransportDescriptor &t) const

Comparison operator.

20.3.5.2. SharedMemTransportDescriptor
struct test_SharedMemTransportDescriptor : public eprosima::fastdds::rtps::SharedMemTransportDescriptor

Shared memory transport configuration

Public Functions

virtual TransportInterface *create_transport() const override

Factory method pattern. It will create and return a TransportInterface corresponding to this descriptor. This provides an interface to the NetworkFactory to create the transports without the need to know about their type

20.4. LOG

eProsima Fast DDS Logging Module API

20.4.1. Colors

A collection of macros for ease the stream coloring.

20.4.1.1. Color Blue
C_BLUE "\033[34m"
20.4.1.2. Color Bright
C_BRIGHT "\033[1m"
20.4.1.3. Color Bright Blue
C_B_BLUE "\033[34;1m"
20.4.1.4. Color Bright Cyan
C_B_CYAN "\033[36;1m"
20.4.1.5. Color Bright Green
C_B_GREEN "\033[32;1m"
20.4.1.6. Color Bright Magenta
C_B_MAGENTA "\033[35;1m"
20.4.1.7. Color Bright Red
C_B_RED "\033[31;1m"
20.4.1.8. Color Bright White
C_B_WHITE "\033[37;1m"
20.4.1.9. Color Bright Yellow
C_B_YELLOW "\033[33;1m"
20.4.1.10. Color Cyan
C_CYAN "\033[36m"
20.4.1.11. Color Def
C_DEF "\033[m"
20.4.1.12. Color Green
C_GREEN "\033[32m"
20.4.1.13. Color Magenta
C_MAGENTA "\033[35m"
20.4.1.14. Color Red
C_RED "\033[31m"
20.4.1.15. Color White
C_WHITE "\033[37m"
20.4.1.16. Color Yellow
C_YELLOW "\033[33m"

20.4.2. FileConsumer

class FileConsumer : public eprosima::fastdds::dds::OStreamConsumer

Public Functions

FileConsumer()

Default constructor: filename = “output.log”, append = false.

FileConsumer(const std::string &filename, bool append = false)

Constructor with parameters.

Parameters:
  • filename – path of the output file where the log will be wrote.

  • append – indicates if the consumer must append the content in the filename.

20.4.3. Log

class Log

Logging utilities. Logging is accessed through the three macros above, and configuration on the log output can be achieved through static methods on the class. Logging at various levels can be disabled dynamically (through the Verbosity level) or statically (through the LOG_NO_[VERB] macros) for maximum performance.

Public Types

enum Kind

Types of log entry.

  • Error: Maximum priority. Can only be disabled statically through LOG_NO_ERROR.

  • Warning: Medium priority. Can be disabled statically and dynamically.

  • Info: Low priority. Useful for debugging. Disabled by default on release branches.

Values:

enumerator Error
enumerator Warning
enumerator Info

Public Static Functions

static void RegisterConsumer(std::unique_ptr<LogConsumer> &&consumer)

Registers an user defined consumer to route log output. There is a default stdout consumer active as default.

Parameters:

consumer – r-value to a consumer unique_ptr. It will be invalidated after the call.

static void ClearConsumers()

Removes all registered consumers, including the default stdout.

static void ReportFilenames(bool)

Enables the reporting of filenames in log entries. Disabled by default.

static void ReportFunctions(bool)

Enables the reporting of function names in log entries. Enabled by default when supported.

static void SetVerbosity(Log::Kind)

Sets the verbosity level, allowing for messages equal or under that priority to be logged.

static Log::Kind GetVerbosity()

Returns the current verbosity level.

static void SetCategoryFilter(const std::regex&)

Sets a filter that will pattern-match against log categories, dropping any unmatched categories.

static void UnsetCategoryFilter()

Unset the category filter.

static bool HasCategoryFilter()

Returns whether a category filter was set or not.

static std::regex GetCategoryFilter()

Returns a copy of the current category filter or an empty object otherwise.

static void SetFilenameFilter(const std::regex&)

Sets a filter that will pattern-match against filenames, dropping any unmatched categories.

static std::regex GetFilenameFilter()

Returns a copy of the current filename filter or an empty object otherwise.

static void SetErrorStringFilter(const std::regex&)

Sets a filter that will pattern-match against the provided error string, dropping any unmatched categories.

static void SetThreadConfig(const rtps::ThreadSettings&)

Sets thread configuration for the logging thread.

static std::regex GetErrorStringFilter()

Returns a copy of the current error string filter or an empty object otherwise.

static void Reset()

Returns the logging engine to configuration defaults.

static void Flush()

Waits until all info logged up to the call time is consumed.

static void KillThread()

Stops the logging thread. It will re-launch on the next call to a successful log macro.

static void QueueLog(const std::string &message, const Log::Context&, Log::Kind)

Not recommended to call this method directly! Use the following macros:

This is a very high sensible point of the code and it should be refactored to be as efficient as possible.

struct Context
struct Entry

20.4.4. LogConsumer

class LogConsumer

Consumes a log entry to output it somewhere.

Subclassed by eprosima::fastdds::dds::OStreamConsumer

20.4.5. EPROSIMA_LOG_ERROR

EPROSIMA_LOG_ERROR(cat, msg) EPROSIMA_LOG_ERROR_IMPL_(cat, msg)

Logs an error. Disable reporting through define LOG_NO_ERROR.

20.4.6. EPROSIMA_LOG_INFO

EPROSIMA_LOG_INFO(cat, msg) EPROSIMA_LOG_INFO_IMPL_(cat, msg)

Logs an info message. Disable it through Log::SetVerbosity, define LOG_NO_INFO, or being in a release branch.

eProsima log layer. Logging categories and verbosity can be specified dynamically at runtime. However, even on a category not covered by the current verbosity level, there is some overhead on calling a log macro. For maximum performance, you can opt out of logging any particular level by defining the following symbols:

  • define LOG_NO_ERROR

  • define LOG_NO_WARNING

  • define LOG_NO_INFO

Additionally. the lowest level (Info) is disabled by default on release branches.

20.4.7. EPROSIMA_LOG_WARNING

EPROSIMA_LOG_WARNING(cat, msg) EPROSIMA_LOG_WARNING_IMPL_(cat, msg)

Logs a warning. Disable reporting through Log::SetVerbosity or define LOG_NO_WARNING.

20.4.8. OStreamConsumer

class OStreamConsumer : public eprosima::fastdds::dds::LogConsumer

Subclassed by eprosima::fastdds::dds::FileConsumer, eprosima::fastdds::dds::StdoutConsumer, eprosima::fastdds::dds::StdoutErrConsumer

20.4.9. StdoutConsumer

class StdoutConsumer : public eprosima::fastdds::dds::OStreamConsumer

20.4.10. StdoutErrConsumer

class StdoutErrConsumer : public eprosima::fastdds::dds::OStreamConsumer

Public Functions

virtual void stderr_threshold(const Log::Kind &kind)

Set the stderr_threshold to a Log::Kind. This threshold decides which log messages are output on STDOUT, and which are output to STDERR. Log messages with a Log::Kind equal to or more severe than the stderr_threshold are output to STDERR using std::cerr. Log messages with a Log::Kind less severe than the stderr_threshold are output to STDOUT using std::cout.

Parameters:

kind – The Log::Kind to which stderr_threshold is set.

virtual Log::Kind stderr_threshold() const

Retrieve the stderr_threshold.

Returns:

The Log::Kind to which stderr_threshold is set.

Public Static Attributes

static constexpr Log::Kind STDERR_THRESHOLD_DEFAULT = Log::Kind::Warning

Default value of stderr_threshold.

20.5. Statistics

eProsima Fast DDS Statistics Module extension API.

20.5.1. DomainParticipant

class DomainParticipant : public eprosima::fastdds::dds::DomainParticipant

Class DomainParticipant: extends standard DDS DomainParticipant class to include specific methods for the Statistics module

Public Functions

fastdds::dds::ReturnCode_t enable_statistics_datawriter(const std::string &topic_name, const eprosima::fastdds::dds::DataWriterQos &dwqos)

This operation enables a Statistics DataWriter.

Parameters:
  • topic_name[in] Name of the topic associated to the Statistics DataWriter

  • dwqos[in] DataWriterQos to be set

Returns:

RETCODE_UNSUPPORTED if the FASTDDS_STATISTICS CMake option has not been set, RETCODE_BAD_PARAMETER if the topic name provided does not correspond to any Statistics DataWriter, RETCODE_INCONSISTENT_POLICY if the DataWriterQos provided are inconsistent, RETCODE_OK if the DataWriter has been created or if it has been created previously, and RETCODE_ERROR otherwise

fastdds::dds::ReturnCode_t enable_statistics_datawriter_with_profile(const std::string &profile_name, const std::string &topic_name)

This operation enables a Statistics DataWriter from a given profile.

Parameters:
  • profile_name[in] DataWriter QoS profile name

  • topic_name[in] Name of the statistics topic to be enabled.

Returns:

RETCODE_UNSUPPORTED if the FASTDDS_STATISTICS CMake option has not been set, RETCODE_BAD_PARAMETER if the topic name provided does not correspond to any Statistics DataWriter, RETCODE_INCONSISTENT_POLICY if the DataWriterQos provided in profile are inconsistent, RETCODE_OK if the DataWriter has been created or if it has been created previously, and RETCODE_ERROR otherwise

fastdds::dds::ReturnCode_t disable_statistics_datawriter(const std::string &topic_name)

This operation disables a Statistics DataWriter.

Parameters:

topic_name – Name of the topic associated to the Statistics DataWriter

Returns:

RETCODE_UNSUPPORTED if the FASTDDS_STATISTICS CMake option has not been set, RETCODE_BAD_PARAMETER if the topic name provided does not correspond to any Statistics DataWriter, RETCODE_OK if the DataWriter has been correctly deleted or does not exist, and RETCODE_ERROR otherwise

eprosima::fastdds::dds::ReturnCode_t enable_monitor_service()

Enables the monitor service in the DomainParticipant.

Note

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Returns:

RETCODE_OK if the monitor service could be correctly enabled.

Returns:

RETCODE_ERROR if the monitor service could not be enabled properly.

Returns:

RETCODE_UNSUPPORTED if FASTDDS_STATISTICS is not enabled.

eprosima::fastdds::dds::ReturnCode_t disable_monitor_service()

Disables the monitor service in this DomainParticipant. Does nothing if the service was not enabled before.

Note

Not supported yet. Currently returns RETCODE_UNSUPPORTED

Returns:

RETCODE_OK if the monitor service could be correctly disabled.

Returns:

RETCODE_NOT_ENABLED if the monitor service was not previously enabled.

Returns:

RETCODE_ERROR if the service could not be properly disabled.

Returns:

RETCODE_UNSUPPORTED if FASTDDS_STATISTICS is not enabled.

eprosima::fastdds::dds::ReturnCode_t fill_discovery_data_from_cdr_message(fastdds::dds::ParticipantBuiltinTopicData &data, const statistics::MonitorServiceStatusData &msg)

fills in the ParticipantBuiltinTopicData from a MonitorService Message

Parameters:
  • data[out] Proxy to fill

  • msg[in] MonitorService Message to get the proxy information from.

Returns:

RETCODE_OK if the operation succeeds.

Returns:

RETCODE_ERROR if the operation fails.

eprosima::fastdds::dds::ReturnCode_t fill_discovery_data_from_cdr_message(fastdds::dds::PublicationBuiltinTopicData &data, const statistics::MonitorServiceStatusData &msg)

fills in the PublicationBuiltinTopicData from a MonitorService Message

Parameters:
  • data[out] Proxy to fill.

  • msg[in] MonitorService Message to get the proxy information from.

Returns:

RETCODE_OK if the operation succeeds.

Returns:

RETCODE_ERROR if the operation fails.

eprosima::fastdds::dds::ReturnCode_t fill_discovery_data_from_cdr_message(fastdds::dds::SubscriptionBuiltinTopicData &data, const statistics::MonitorServiceStatusData &msg)

fills in the SubscriptionBuiltinTopicData from a MonitorService Message

Parameters:
  • data[out] Proxy to fill.

  • msg[in] MonitorService Message to get the proxy information from.

Returns:

RETCODE_OK if the operation succeeds.

Returns:

RETCODE_ERROR if the operation fails.

Public Static Functions

static DomainParticipant *narrow(eprosima::fastdds::dds::DomainParticipant *domain_participant)

This operation narrows the DDS DomainParticipant to the Statistics DomainParticipant.

Parameters:

domain_participant – Reference to the DDS DomainParticipant

Returns:

Reference to the Statistics DomainParticipant if successful. nullptr otherwise.

static const DomainParticipant *narrow(const eprosima::fastdds::dds::DomainParticipant *domain_participant)

This operation narrows the DDS DomainParticipant to the Statistics DomainParticipant.

Parameters:

domain_participant – Constant reference to the DDS DomainParticipant

Returns:

Constant reference to the Statistics DomainParticipant if successful. nullptr otherwise.

20.5.2. DataWriterQos

class DataWriterQos : public eprosima::fastdds::dds::DataWriterQos

Class DataWriterQos: extends standard DDS DataWriterQos class to include specific default constructor for the recommended DataWriterQos profile.

Public Functions

DataWriterQos()

Constructor.

const eprosima::fastdds::statistics::dds::DataWriterQos eprosima::fastdds::statistics::dds::STATISTICS_DATAWRITER_QOS

Constant to access default Statistics DataWriter Qos.

20.5.3. DataReaderQos

class DataReaderQos : public eprosima::fastdds::dds::DataReaderQos

Class DataReaderQos: extends standard DDS DataReaderQos class to include specific default constructor for the recommended DataReaderQos profile.

Public Functions

DataReaderQos()

Constructor.

const eprosima::fastdds::statistics::dds::DataReaderQos eprosima::fastdds::statistics::dds::STATISTICS_DATAREADER_QOS

Constant to access default Statistics DataReader Qos.

class MonitorServiceDataReaderQos : public eprosima::fastdds::dds::DataReaderQos

Class MonitorServiceDataReaderQos: extends standard DDS DataReaderQos class to include specific default constructor for the recommended MonitorServiceDataReaderQos profile.

Public Functions

MonitorServiceDataReaderQos()

Constructor.

const eprosima::fastdds::statistics::dds::MonitorServiceDataReaderQos eprosima::fastdds::statistics::dds::MONITOR_SERVICE_DATAREADER_QOS

Constant to access default Monitor Service Statistics DataReader Qos.

20.5.4. Topic names

constexpr const char *eprosima::fastdds::statistics::HISTORY_LATENCY_TOPIC = "_fastdds_statistics_history2history_latency"

Statistic topic that reports the write-to-notification latency between any two pairs of matched DataWriter-DataReader histories

constexpr const char *eprosima::fastdds::statistics::NETWORK_LATENCY_TOPIC = "_fastdds_statistics_network_latency"

Statistics topic that reports the network latency (message group to message receiver) between any two communicating locators

constexpr const char *eprosima::fastdds::statistics::PUBLICATION_THROUGHPUT_TOPIC = "_fastdds_statistics_publication_throughput"

Statistic topic that reports the publication’s throughput (amount of data sent) for every DataWriter.

constexpr const char *eprosima::fastdds::statistics::SUBSCRIPTION_THROUGHPUT_TOPIC = "_fastdds_statistics_subscription_throughput"

Statistics topic that reports the subscription’s throughput (amount of data received) for every DataReader.

constexpr const char *eprosima::fastdds::statistics::RTPS_SENT_TOPIC = "_fastdds_statistics_rtps_sent"

Statistics topic that reports the number of RTPS packets and bytes sent to each locator.

constexpr const char *eprosima::fastdds::statistics::RTPS_LOST_TOPIC = "_fastdds_statistics_rtps_lost"

Statistics topic that reports the number of RTPS packets and bytes that have been lost in the network.

constexpr const char *eprosima::fastdds::statistics::RESENT_DATAS_TOPIC = "_fastdds_statistics_resent_datas"

Statistics topic that reports the number of DATA/DATAFRAG sub-messages resent.

constexpr const char *eprosima::fastdds::statistics::HEARTBEAT_COUNT_TOPIC = "_fastdds_statistics_heartbeat_count"

Statistics topic that reports the number of HEARTBEATs that each non discovery DataWriter sends.

constexpr const char *eprosima::fastdds::statistics::ACKNACK_COUNT_TOPIC = "_fastdds_statistics_acknack_count"

Statistics topic that reports the number of ACKNACKs that each non discovery DataReader sends.

constexpr const char *eprosima::fastdds::statistics::NACKFRAG_COUNT_TOPIC = "_fastdds_statistics_nackfrag_count"

Statistics topic that reports the number of NACKFRAGs that each non discovery DataReader sends.

constexpr const char *eprosima::fastdds::statistics::GAP_COUNT_TOPIC = "_fastdds_statistics_gap_count"

Statistics topic that reports the number of GAPs that each non discovery DataWriter sends.

constexpr const char *eprosima::fastdds::statistics::DATA_COUNT_TOPIC = "_fastdds_statistics_data_count"

Statistics topic that reports the number of DATA/DATAFRAG sub-messages that each non discovery DataWriter sends.

constexpr const char *eprosima::fastdds::statistics::PDP_PACKETS_TOPIC = "_fastdds_statistics_pdp_packets"

Statistics topic that reports the number of PDP discovery traffic RTPS packets transmitted by each DDS participant.

constexpr const char *eprosima::fastdds::statistics::EDP_PACKETS_TOPIC = "_fastdds_statistics_edp_packets"

Statistics topic that reports the number of EDP discovery traffic RTPS packets transmitted by each DDS participant.

constexpr const char *eprosima::fastdds::statistics::DISCOVERY_TOPIC = "_fastdds_statistics_discovered_entity"

Statistics topic that reports when new entities are discovered.

constexpr const char *eprosima::fastdds::statistics::SAMPLE_DATAS_TOPIC = "_fastdds_statistics_sample_datas"

Statistics topic that reports the number of DATA/DATAFRAG sub-messages needed to send a single sample.

constexpr const char *eprosima::fastdds::statistics::PHYSICAL_DATA_TOPIC = "_fastdds_statistics_physical_data"

Statistics topic that reports the host, user and process where the module is running.

21. Python API Reference

This section presents the most commonly used Python APIs provided by Fast DDS.

21.1. DDS DCPS PIM

Data Distribution Service (DDS) Data-Centric Publish-Subscribe (DCPS) Platform Independent Model (PIM) API

21.1.1. Core

21.1.1.1. Entity
class fastdds.Entity(*args, **kwargs)

The Entity class is the abstract base class for all the objects that support QoS policies, a listener and a status condition.

close()

This operation disables the Entity before closing it

enable()

This operation enables the Entity

Return type:

int

Returns:

RETCODE_OK

get_instance_handle()

Retrieves the instance handler that represents the Entity

Return type:

InstanceHandle_t

Returns:

Reference to the InstanceHandle

get_status_changes()

Retrieves the set of triggered statuses in the Entity

Triggered statuses are the ones whose value has changed since the last time the application read the status. When the entity is first created or if the entity is not enabled, all communication statuses are in the non-triggered state, so the list returned by the get_status_changes operation will be empty. The list of statuses returned by the get_status_changes operation refers to the status that are triggered on the Entity itself and does not include statuses that apply to contained entities.

Return type:

StatusMask

Returns:

const reference to the StatusMask with the triggered statuses set to 1

get_status_mask()

Retrieves the set of relevant statuses for the Entity

Return type:

StatusMask

Returns:

Reference to the StatusMask with the relevant statuses set to 1

get_statuscondition(*args)

Overload 1:

Allows access to the StatusCondition associated with the Entity

Return type:

StatusCondition

Returns:

Reference to StatusCondition object


Overload 2:

Allows access to the StatusCondition associated with the Entity

Return type:

StatusCondition

Returns:

Const Reference to StatusCondition object

is_enabled()

Checks if the Entity is enabled

Return type:

boolean

Returns:

true if enabled, false if not

property thisown

The membership flag

21.1.1.2. DomainEntity
class fastdds.DomainEntity(*args, **kwargs)

The DomainEntity class is a subclass of Entity created in order to differentiate between DomainParticipants and the rest of Entities

property thisown

The membership flag

21.1.1.3. Policy
21.1.1.3.1. DataRepresentationId
class fastdds.XCDR_DATA_REPRESENTATION(*args: Any, **kwargs: Any)
class fastdds.XML_DATA_REPRESENTATION(*args: Any, **kwargs: Any)
class fastdds.XCDR2_DATA_REPRESENTATION(*args: Any, **kwargs: Any)
class fastdds.DEFAULT_DATA_REPRESENTATION(*args: Any, **kwargs: Any)
21.1.1.3.2. DataRepresentationQosPolicy
class fastdds.DataRepresentationQosPolicy

With multiple standard data Representations available, and vendor-specific extensions possible, DataWriters and DataReaders must be able to negotiate which data representation(s) to use. This negotiation shall occur based on DataRepresentationQosPolicy.

Warning: If a writer’s offered representation is contained within a reader’s sequence, the offer satisfies the request and the policies are compatible. Otherwise, they are incompatible.

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

property m_value
List of ‘DataRepresentationId’.

By default, empty list.

property thisown

The membership flag

21.1.1.3.3. DataSharingQosPolicy
class fastdds.DataSharingQosPolicy(*args)

Qos Policy to configure the data sharing

Notes: Immutable Qos Policy

add_domain_id(*args)
automatic(*args)

Overload 1:

Configures the DataSharing in automatic mode

The default shared memory directory of the OS is used. A default domain ID is automatically computed.


Overload 2:

Configures the DataSharing in automatic mode

The default shared memory directory of the OS is used.

Parameters:

domain_ids (std::vector< uint16_t,std::allocator< uint16_t > >) – the user configured DataSharing domain IDs (16 bits).


Overload 3:

Configures the DataSharing in automatic mode

A default domain ID is automatically computed.

Parameters:

directory (string) – The shared memory directory to use.


Overload 4:

Configures the DataSharing in automatic mode

Parameters:
  • directory (string) – The shared memory directory to use.

  • domain_ids (std::vector< uint16_t,std::allocator< uint16_t > >) – the user configured DataSharing domain IDs (16 bits).

clear()

Clears the QosPolicy object

data_sharing_listener_thread(*args)

Overload 1:

Getter for DataSharing listener thread ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 2:

Getter for DataSharing listener thread ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 3:

Setter for the DataSharing listener thread ThreadSettings

Parameters:

value (ThreadSettings) – New ThreadSettings to be set

domain_ids()

Gets the set of DataSharing domain IDs.

Each domain ID is 64 bit long. However, user-defined domain IDs are only 16 bit long, while the rest of the 48 bits are used for the automatically generated domain ID (if any).

  • Automatic domain IDs use the 48 MSB and leave the 16 LSB as zero.

  • User defined domain IDs use the 16 LSB and leave the 48 MSB as zero.

Return type:

std::vector< uint64_t,std::allocator< uint64_t > >

Returns:

the current DataSharing domain IDs

kind()
Return type:

int

Returns:

the current DataSharing configuration mode

max_domains()
Return type:

int

Returns:

the current configured maximum number of domain IDs

off()

Configures the DataSharing in disabled mode

on(*args)

Overload 1:

Configures the DataSharing in active mode

A default domain ID is automatically computed.

Parameters:

directory (string) – The shared memory directory to use. It is mandatory to provide a non-empty name or the creation of endpoints will fail.


Overload 2:

Configures the DataSharing in active mode

Parameters:
  • directory (string) – The shared memory directory to use. It is mandatory to provide a non-empty name or the creation of endpoints will fail.

  • domain_ids (std::vector< uint16_t,std::allocator< uint16_t > >) – the user configured DataSharing domain IDs (16 bits).

set_max_domains(size)
Parameters:

size (int) – the new maximum number of domain IDs

shm_directory()
Return type:

string

Returns:

the current DataSharing shared memory directory

property thisown

The membership flag

21.1.1.3.4. DataSharingKind
class fastdds.AUTO(*args: Any, **kwargs: Any)
class fastdds.ON(*args: Any, **kwargs: Any)
class fastdds.OFF(*args: Any, **kwargs: Any)
21.1.1.3.5. DeadlineQosPolicy
class fastdds.DeadlineQosPolicy

DataReader expects a new sample updating the value of each instance at least once every deadline period. DataWriter indicates that the application commits to write a new value (using the DataWriter) for each instance managed by the DataWriter at least once every deadline period.

Notes: Mutable Qos Policy

clear()

Clears the QosPolicy object

property period

Maximum time expected between samples. It is inconsistent for a DataReader to have a DEADLINE period less than its TimeBasedFilterQosPolicy minimum_separation.

By default, c_TimeInifinite.

property thisown

The membership flag

21.1.1.3.6. DestinationOrderQosPolicy
class fastdds.DestinationOrderQosPolicy

Controls the criteria used to determine the logical order among changes made by Publisher entities to the same instance of data (i.e., matching Topic and key).

Warning: This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

property kind
DestinationOrderQosPolicyKind.

By default, BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS.

property thisown

The membership flag

21.1.1.3.7. DestinationOrderQosPolicyKind
class fastdds.BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS(*args: Any, **kwargs: Any)
class fastdds.BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS(*args: Any, **kwargs: Any)
21.1.1.3.8. DisablePositiveACKsQosPolicy
class fastdds.DisablePositiveACKsQosPolicy

Class DisablePositiveACKsQosPolicy to disable sending of positive ACKs

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

property duration

The duration to keep samples for (not serialized as not needed by reader). By default, dds::c_TimeInfinite

property enabled

True if this QoS is enabled. By default, false

property thisown

The membership flag

21.1.1.3.9. DurabilityQosPolicy
class fastdds.DurabilityQosPolicy

This policy expresses if the data should ‘outlive’ their writing time.

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

durabilityKind(*args)

Overload 1:

Translates kind to rtps layer equivalent

Return type:

int

Returns:

fastdds::rtps::DurabilityKind_t


Overload 2:

Set kind passing the rtps layer equivalent kind

Parameters:

new_kind (int) – fastdds::rtps::DurabilityKind_t

property kind

DurabilityQosPolicyKind.

By default the value for DataReaders: VOLATILE_DURABILITY_QOS, for DataWriters TRANSIENT_LOCAL_DURABILITY_QOS

property thisown

The membership flag

21.1.1.3.10. DurabilityQosPolicyKind
class fastdds.VOLATILE_DURABILITY_QOS(*args: Any, **kwargs: Any)
class fastdds.TRANSIENT_LOCAL_DURABILITY_QOS(*args: Any, **kwargs: Any)
class fastdds.TRANSIENT_DURABILITY_QOS(*args: Any, **kwargs: Any)
class fastdds.PERSISTENT_DURABILITY_QOS(*args: Any, **kwargs: Any)
21.1.1.3.11. DurabilityServiceQosPolicy
class fastdds.DurabilityServiceQosPolicy

Specifies the configuration of the durability service. That is, the service that implements the DurabilityQosPolicy kind of TRANSIENT and PERSISTENT.

Warning: This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

property history_depth

Number of most recent values that should be maintained on the History. It only have effect if the history_kind is KEEP_LAST_HISTORY_QOS.

By default, 1.

property history_kind

Controls the HistoryQosPolicy of the fictitious DataReader that stores the data within the durability service.

By default, KEEP_LAST_HISTORY_QOS.

property max_instances

Control the ResourceLimitsQos of the implied DataReader that stores the data within the durability service. Represents the maximum number of instances DataWriter (or DataReader) can manage.

By default, LENGTH_UNLIMITED.

property max_samples

Control the ResourceLimitsQos of the implied DataReader that stores the data within the durability service. Specifies the maximum number of data-samples the DataWriter (or DataReader) can manage across all the instances associated with it. Represents the maximum samples the middleware can store for any one DataWriter (or DataReader). It is inconsistent for this value to be less than max_samples_per_instance.

By default, LENGTH_UNLIMITED.

property max_samples_per_instance

Control the ResourceLimitsQos of the implied DataReader that stores the data within the durability service. Represents the maximum number of samples of any one instance a DataWriter(or DataReader) can manage. It is inconsistent for this value to be greater than max_samples.

By default, LENGTH_UNLIMITED.

property service_cleanup_delay

Control when the service is able to remove all information regarding a data-instance.

By default, dds::c_TimeZero.

property thisown

The membership flag

21.1.1.3.12. EntityFactoryQosPolicy
class fastdds.EntityFactoryQosPolicy(*args)

Controls the behavior of the entity when acting as a factory for other entities. In other words, configures the side-effects of the create_* and delete_* operations.

Notes: Mutable Qos Policy

property autoenable_created_entities

Specifies whether the entity acting as a factory automatically enables the instances it creates. If True the factory will automatically enable each created Entity otherwise it will not.

By default, True.

clear()
property thisown

The membership flag

21.1.1.3.13. GenericDataQosPolicy
class fastdds.GenericDataQosPolicy(*args)

Class GenericDataQosPolicy, base class to transmit user data during the discovery phase.

clear()

Clears the QosPolicy object

dataVec()
Return type:

eprosima::fastdds::ResourceLimitedVector< unsigned char >::collection_type

Returns:

const reference to the internal raw data.

data_vec(*args)

Overload 1:

Returns raw data vector.

Return type:

eprosima::fastdds::ResourceLimitedVector< unsigned char >::collection_type

Returns:

raw data as vector of octets.


Overload 2:

Returns raw data vector.

Return type:

eprosima::fastdds::ResourceLimitedVector< unsigned char >::collection_type

Returns:

raw data as vector of octets.


Overload 3:

Sets raw data vector.

Parameters:

vec (eprosima::fastdds::ResourceLimitedVector< unsigned char >::collection_type) – raw data to set.

getValue()

Returns raw data vector.

Return type:

eprosima::fastdds::ResourceLimitedVector< unsigned char >::collection_type

Returns:

raw data as vector of octets.

resize(new_size)
setValue(vec)

Sets raw data vector.

Parameters:

vec (eprosima::fastdds::ResourceLimitedVector< unsigned char >::collection_type) – raw data to set.

set_max_size(size)

Set the maximum size of the user data and reserves memory for that much.

Parameters:

size (int) – new maximum size of the user data. Zero for unlimited size

property thisown

The membership flag

21.1.1.3.14. GroupDataQosPolicy
class fastdds.GroupDataQosPolicy(*args)
property thisown

The membership flag

21.1.1.3.15. HistoryQosPolicy
class fastdds.HistoryQosPolicy

Specifies the behavior of the Service in the case where the value of a sample changes (one or more times) before it can be successfully communicated to one or more existing subscribers. This QoS policy controls whether the Service should deliver only the most recent value, attempt to deliver all intermediate values, or do something in between. On the publishing side this policy controls the samples that should be maintained by the DataWriter on behalf of existing DataReader entities. The behavior with regards to a DataReaderentities discovered after a sample is written is controlled by the DURABILITY QoS policy. On the subscribing side it controls the samples that should be maintained until the application “takes” them from the Service.

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

property depth

History depth. By default, 1. If a value other than 1 is specified, it should be consistent with the settings of the ResourceLimitsQosPolicy.

Warning: Only takes effect if the kind is KEEP_LAST_HISTORY_QOS.

property kind
HistoryQosPolicyKind.

By default, KEEP_LAST_HISTORY_QOS.

property thisown

The membership flag

21.1.1.3.16. HistoryQosPolicyKind
class fastdds.KEEP_LAST_HISTORY_QOS(*args: Any, **kwargs: Any)
class fastdds.KEEP_ALL_HISTORY_QOS(*args: Any, **kwargs: Any)
21.1.1.3.17. LatencyBudgetQosPolicy
class fastdds.LatencyBudgetQosPolicy

Specifies the maximum acceptable delay from the time the data is written until the data is inserted in the receiver’s application-cache and the receiving application is notified of the fact.This policy is a hint to the Service, not something that must be monitored or enforced. The Service is not required to track or alert the user of any violation.

Warning: This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Notes: Mutable Qos Policy

clear()

Clears the QosPolicy object

property duration
Maximum acceptable delay from the time data is written until it is received.

By default, dds::c_TimeZero.

property thisown

The membership flag

21.1.1.3.18. LifespanQosPolicy
class fastdds.LifespanQosPolicy

Specifies the maximum duration of validity of the data written by the DataWriter.

Notes: Mutable Qos Policy

clear()

Clears the QosPolicy object

property duration

Period of validity. By default, dds::c_TimeInfinite.

property thisown

The membership flag

21.1.1.3.19. LivelinessQosPolicy
class fastdds.LivelinessQosPolicy

Determines the mechanism and parameters used by the application to determine whether an Entity is “active” (alive). The “liveliness” status of an Entity is used to maintain instance ownership in combination with the setting of the OwnershipQosPolicy. The application is also informed via listener when an Entity is no longer alive.

The DataReader requests that liveliness of the writers is maintained by the requested means and loss of liveliness is detected with delay not to exceed the lease_duration.

The DataWriter commits to signaling its liveliness using the stated means at intervals not to exceed the lease_duration. Listeners are used to notify the DataReaderof loss of liveliness and DataWriter of violations to the liveliness contract.

property announcement_period

The period for automatic assertion of liveliness. Only used for DataWriters with AUTOMATIC liveliness. By default, dds::c_TimeInfinite.

Warning: When not infinite, must be < lease_duration, and it is advisable to be less than 0.7*lease_duration.

clear()

Clears the QosPolicy object

property kind

Liveliness kind By default, AUTOMATIC_LIVELINESS.

property lease_duration

Period within which liveliness should be asserted. On a DataWriter it represents the period it commits to signal its liveliness. On a DataReader it represents the period without assertion after which a DataWriter is considered inactive. By default, dds::c_TimeInfinite.

property thisown

The membership flag

21.1.1.3.20. LivelinessQosPolicyKind
class fastdds.AUTOMATIC_LIVELINESS_QOS(*args: Any, **kwargs: Any)
class fastdds.MANUAL_BY_PARTICIPANT_LIVELINESS_QOS(*args: Any, **kwargs: Any)
class fastdds.MANUAL_BY_TOPIC_LIVELINESS_QOS(*args: Any, **kwargs: Any)
21.1.1.3.21. OwnershipQosPolicy
class fastdds.OwnershipQosPolicy

Specifies whether it is allowed for multiple DataWriters to write the same instance of the data and if so, how these modifications should be arbitrated

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

property kind

OwnershipQosPolicyKind

property thisown

The membership flag

21.1.1.3.22. OwnershipQosPolicyKind
class fastdds.SHARED_OWNERSHIP_QOS(*args: Any, **kwargs: Any)
class fastdds.EXCLUSIVE_OWNERSHIP_QOS(*args: Any, **kwargs: Any)
21.1.1.3.23. OwnershipStrengthQosPolicy
class fastdds.OwnershipStrengthQosPolicy

Specifies the value of the “strength” used to arbitrate among multiple DataWriter objects that attempt to modify the same instance of a data-object (identified by Topic + key).This policy only applies if the OWNERSHIP QoS policy is of kind EXCLUSIVE.

Notes: Mutable Qos Policy

clear()

Clears the QosPolicy object

property thisown

The membership flag

property value

Strength By default, 0.

21.1.1.3.24. ParticipantResourceLimitsQos
21.1.1.3.25. Partition_t
class fastdds.Partition_t(ptr)
name()

Getter for the partition name

Return type:

string

Returns:

name

size()

Getter for the size

Return type:

int

Returns:

uint32_t with the size

property thisown

The membership flag

21.1.1.3.26. PartitionQosPolicy
class fastdds.PartitionQosPolicy(*args)

Set of strings that introduces a logical partition among the topics visible by the Publisher and Subscriber. A DataWriter within a Publisher only communicates with a DataReader in a Subscriber if (in addition to matching the Topic and having compatible QoS) the Publisher and Subscriber have a common partition name string.

The empty string (“”) is considered a valid partition that is matched with other partition names using the same rules of string matching and regular-expression matching used for any other partition name.

Notes: Mutable Qos Policy

begin()

Getter for the first position of the partition list

Return type:

eprosima::fastdds::dds::PartitionQosPolicy::const_iterator

Returns:

const_iterator

clear()

Clears list of partition names

empty()

Check if the set is empty

Return type:

int

Returns:

true if it is empty, false otherwise

end()

Getter for the end of the partition list

Return type:

eprosima::fastdds::dds::PartitionQosPolicy::const_iterator

Returns:

const_iterator

getNames()

Returns partition names.

Return type:

std::vector< std::string,std::allocator< std::string > >

Returns:

Vector of partition name strings.

max_size()

Getter for the maximum size (in bytes)

Return type:

int

Returns:

uint32_t with the maximum size

names(*args)

Overload 1:

Returns partition names.

Return type:

std::vector< std::string,std::allocator< std::string > >

Returns:

Vector of partition name strings.


Overload 2:

Overrides partition names

Parameters:

nam (std::vector< std::string,std::allocator< std::string > >) – Vector of partition name strings.

push_back(name)

Appends a name to the list of partition names.

Parameters:

name (string) – Name to append.

setNames(nam)

Overrides partition names

Parameters:

nam (std::vector< std::string,std::allocator< std::string > >) – Vector of partition name strings.

set_max_size(size)

Setter for the maximum size reserved for partitions (in bytes)

Parameters:

size (int) – Size to be set

size()

Getter for the number of partitions

Return type:

int

Returns:

uint32_t with the size

property thisown

The membership flag

21.1.1.3.27. PresentationQosPolicy
class fastdds.PresentationQosPolicy

Specifies how the samples representing changes to data instances are presented to the subscribing application. This policy affects the application’s ability to specify and receive coherent changes and to see the relative order of changes.access_scope determines the largest scope spanning the entities for which the order and coherency of changes can be preserved. The two booleans control whether coherent access and ordered access are supported within the scope access_scope.

Warning: This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Notes: Immutable Qos Policy

property access_scope
Access Scope Kind

By default, INSTANCE_PRESENTATION_QOS.

clear()

Clears the QosPolicy object

property coherent_access

Specifies support coherent access. That is, the ability to group a set of changes as a unit on the publishing end such that they are received as a unit at the subscribing end. by default, false.

property ordered_access

Specifies support for ordered access to the samples received at the subscription end. That is, the ability of the subscriber to see changes in the same order as they occurred on the publishing end. By default, false.

property thisown

The membership flag

21.1.1.3.28. PresentationQosPolicyAccessScopeKind
class fastdds.INSTANCE_PRESENTATION_QOS(*args: Any, **kwargs: Any)
class fastdds.TOPIC_PRESENTATION_QOS(*args: Any, **kwargs: Any)
class fastdds.GROUP_PRESENTATION_QOS(*args: Any, **kwargs: Any)
21.1.1.3.29. PropertyPolicyQos
21.1.1.3.30. PublishModeQosPolicy
class fastdds.PublishModeQosPolicy

Class PublishModeQosPolicy, defines the publication mode for a specific writer.

clear()

Clears the QosPolicy object

property flow_controller_name

Name of the flow controller used when publish mode kind is ASYNCHRONOUS_PUBLISH_MODE.

Since: 2.4.0

property kind
PublishModeQosPolicyKind

By default, SYNCHRONOUS_PUBLISH_MODE.

property thisown

The membership flag

21.1.1.3.31. PublishModeQosPolicyKind
class fastdds.SYNCHRONOUS_PUBLISH_MODE(*args: Any, **kwargs: Any)
class fastdds.ASYNCHRONOUS_PUBLISH_MODE(*args: Any, **kwargs: Any)
21.1.1.3.32. QosPolicy
class fastdds.QosPolicy(*args, **kwargs)

Class QosPolicy, base for all QoS policies defined for Writers and Readers.

clear()

Clears the QosPolicy object

property hasChanged

Boolean that indicates if the Qos has been changed with respect to the default Qos.

send_always()

Whether it should always be sent.

Return type:

boolean

Returns:

True if it should always be sent.

property thisown

The membership flag

21.1.1.3.33. QosPolicyId_t
class fastdds.INVALID_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.USERDATA_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.DURABILITY_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.PRESENTATION_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.DEADLINE_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.LATENCYBUDGET_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.OWNERSHIP_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.OWNERSHIPSTRENGTH_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.LIVELINESS_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.TIMEBASEDFILTER_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.PARTITION_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.RELIABILITY_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.DESTINATIONORDER_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.HISTORY_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.RESOURCELIMITS_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.ENTITYFACTORY_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.WRITERDATALIFECYCLE_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.READERDATALIFECYCLE_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.TOPICDATA_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.GROUPDATA_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.TRANSPORTPRIORITY_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.LIFESPAN_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.DURABILITYSERVICE_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.DATAREPRESENTATION_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.TYPECONSISTENCYENFORCEMENT_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.DISABLEPOSITIVEACKS_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.PARTICIPANTRESOURCELIMITS_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.PROPERTYPOLICY_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.PUBLISHMODE_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.READERRESOURCELIMITS_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.RTPSENDPOINT_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.RTPSRELIABLEREADER_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.RTPSRELIABLEWRITER_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.TRANSPORTCONFIG_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.TYPECONSISTENCY_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.WIREPROTOCOLCONFIG_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.WRITERRESOURCELIMITS_QOS_POLICY_ID(*args: Any, **kwargs: Any)
class fastdds.NEXT_QOS_POLICY_ID(*args: Any, **kwargs: Any)
21.1.1.3.34. ReaderDataLifecycleQosPolicy
class fastdds.ReaderDataLifecycleQosPolicy

Specifies the behavior of the DataReader with regards to the lifecycle of the data-instances it manages. Warning: This Qos Policy will be implemented in future releases. Notes: Mutable Qos Policy

property autopurge_disposed_samples_delay

Indicates the duration the DataReader must retain information regarding instances that have the instance_state NOT_ALIVE_DISPOSED.

By default, dds::c_TimeInfinite.

property autopurge_no_writer_samples_delay

Indicates the duration the DataReader must retain information regarding instances that have the instance_state NOT_ALIVE_NO_WRITERS.

By default, dds::c_TimeInfinite.

clear()
property thisown

The membership flag

21.1.1.3.35. ReliabilityQosPolicy
class fastdds.ReliabilityQosPolicy

Indicates the reliability of the endpoint.

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

property kind

Defines the reliability kind of the endpoint.

By default, BEST_EFFORT_RELIABILITY_QOS for DataReaders and RELIABLE_RELIABILITY_QOS for DataWriters.

property max_blocking_time

Defines the maximum period of time certain methods will be blocked.

Methods affected by this property are: - DataWriter::write - DataReader::takeNextData - DataReader::readNextData

By default, 100 ms.

property thisown

The membership flag

21.1.1.3.36. ReliabilityQosPolicyKind
class fastdds.BEST_EFFORT_RELIABILITY_QOS(*args: Any, **kwargs: Any)
class fastdds.RELIABLE_RELIABILITY_QOS(*args: Any, **kwargs: Any)
21.1.1.3.37. ResourceLimitsQosPolicy
class fastdds.ResourceLimitsQosPolicy

Specifies the resources that the Service can consume in order to meet the requested QoS

Notes: Immutable Qos Policy

property allocated_samples

Number of samples currently allocated.

By default, 100.

clear()

Clears the QosPolicy object

property extra_samples

Represents the extra number of samples available once the max_samples have been reached in the history. This makes it possible, for example, to loan samples even with a full history. By default, 1.

property max_instances

Represents the maximum number of instances DataWriter (or DataReader) can manage.

Value less or equal to 0 means infinite resources. By default, 10.

Warning: It is inconsistent if (max_instances * max_samples_per_instance) > max_samples.

property max_samples

Specifies the maximum number of data-samples the DataWriter (or DataReader) can manage across all the instances associated with it. Represents the maximum samples the middleware can store for any one DataWriter (or DataReader).

Value less or equal to 0 means infinite resources. By default, 5000.

Warning: It is inconsistent if max_samples < (max_instances * max_samples_per_instance).

property max_samples_per_instance

Represents the maximum number of samples of any one instance a DataWriter(or DataReader) can manage.

Value less or equal to 0 means infinite resources. By default, 400.

Warning: It is inconsistent if (max_instances * max_samples_per_instance) > max_samples.

property thisown

The membership flag

21.1.1.3.38. RTPSEndpointQos
class fastdds.RTPSEndpointQos

Qos Policy to configure the endpoint

clear()
property entity_id

Entity ID, if the user wants to specify the EntityID of the endpoint. By default, -1.

property external_unicast_locators

The collection of external locators to use for communication.

property history_memory_policy

Underlying History memory policy. By default, PREALLOCATED_WITH_REALLOC_MEMORY_MODE.

property ignore_non_matching_locators

Whether locators that don’t match with the announced locators should be kept.

property multicast_locator_list

Multicast locator list

property remote_locator_list

Remote locator list

property thisown

The membership flag

property unicast_locator_list

Unicast locator list

property user_defined_id

User Defined ID, used for StaticEndpointDiscovery. By default, -1.

21.1.1.3.39. TimeBasedFilterQosPolicy
class fastdds.TimeBasedFilterQosPolicy

Filter that allows a DataReader to specify that it is interested only in (potentially) a subset of the values of the data. The filter states that the DataReader does not want to receive more than one value each minimum_separation, regardless of how fast the changes occur. It is inconsistent for a DataReader to have a minimum_separation longer than its Deadline period.

Warning: This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Notes: Mutable Qos Policy

clear()

Clears the QosPolicy object

property minimum_separation

Minimum interval between samples. By default, dds::c_TimeZero (the DataReader is interested in all values)

property thisown

The membership flag

21.1.1.3.40. TopicDataQosPolicy
class fastdds.TopicDataQosPolicy(*args)
property thisown

The membership flag

21.1.1.3.41. TransportConfigQos
class fastdds.TransportConfigQos

Qos Policy to configure the transport layer

property builtin_transports_reception_threads_

Thread settings for the builtin transports reception threads

clear()

Clears the QosPolicy object

property listen_socket_buffer_size

Listen socket buffer for all listen resources. Zero value indicates to use default system buffer size.

By default, 0.

property max_msg_size_no_frag

Maximum message size used to avoid fragmentation, set ONLY in LARGE_DATA.

If this value is not zero, the network factory will allow the initialization of UDP transports with maxMessageSize higher than 65500K.

property netmask_filter

Netmask filter configuration

property send_socket_buffer_size

Send socket buffer size for the send resource. Zero value indicates to use default system buffer size.

By default, 0.

property thisown

The membership flag

property use_builtin_transports
Set as false to disable the default UDPv4 implementation.

By default, true.

property user_transports

User defined transports to use alongside or in place of builtins.

21.1.1.3.42. TransportPriorityQosPolicy
class fastdds.TransportPriorityQosPolicy

This policy is a hint to the infrastructure as to how to set the priority of the underlying transport used to send the data.

Warning: This QosPolicy can be defined and is transmitted to the rest of the network but is not implemented in this version.

Notes: Mutable Qos Policy

clear()

Clears the QosPolicy object

property thisown

The membership flag

property value
Priority

By default, 0.

21.1.1.3.43. TypeConsistencyEnforcementQosPolicy
class fastdds.TypeConsistencyEnforcementQosPolicy

The TypeConsistencyEnforcementQosPolicy defines the rules for determining whether the type used to publish a given data stream is consistent with that used to subscribe to it. It applies to DataReaders.

Notes: Immutable Qos Policy

clear()

Clears the QosPolicy object

property m_force_type_validation

This option requires type information to be available in order to complete matching between a DataWriter and DataReader when set to TRUE, otherwise matching can occur without complete type information when set to FALSE.

By default, false.

property m_ignore_member_names

This option controls whether member names are taken into consideration for type assignability. If the option is set to TRUE, member names are considered as part of assignability in addition to member IDs (so that members with the same ID also have the same name). If the option is set to FALSE, then member names are not ignored.

By default, false.

property m_ignore_sequence_bounds

This option controls whether sequence bounds are taken into consideration for type assignability. If the option is set to TRUE, sequence bounds (maximum lengths) are not considered as part of the type assignability. This means that a T2 sequence type with maximum length L2 would be assignable to a T1 sequence type with maximum length L1, even if L2 is greater than L1. If the option is set to false, then sequence bounds are taken into consideration for type assignability and in order for T1 to be assignable from T2 it is required that L1>= L2.

By default, true.

property m_ignore_string_bounds

This option controls whether string bounds are taken into consideration for type assignability. If the option is set to TRUE, string bounds (maximum lengths) are not considered as part of the type assignability. This means that a T2 string type with maximum length L2 would be assignable to a T1 string type with maximum length L1, even if L2 is greater than L1. If the option is set to false, then string bounds are taken into consideration for type assignability and in order for T1 to be assignable from T2 it is required that L1>= L2.

By default, true.

property m_kind
TypeConsistencyKind.

By default, ALLOW_TYPE_COERCION.

property m_prevent_type_widening

This option controls whether type widening is allowed. If the option is set to FALSE, type widening is permitted. If the option is set to TRUE,it shall cause a wider type to not be assignable to a narrower type.

By default, false.

property thisown

The membership flag

21.1.1.3.44. TypeConsistencyKind
class fastdds.DISALLOW_TYPE_COERCION(*args: Any, **kwargs: Any)
class fastdds.ALLOW_TYPE_COERCION(*args: Any, **kwargs: Any)
21.1.1.3.45. UserDataQosPolicy
class fastdds.UserDataQosPolicy(*args)

Class TClassName, base template for data qos policies. Data not known by the middleware, but distributed by means of built-in topics. By default, zero-sized sequence.

Notes: Mutable Qos Policy

property thisown

The membership flag

21.1.1.3.46. WireProtocolConfigQos
class fastdds.WireProtocolConfigQos

Qos Policy that configures the wire protocol

property builtin

Builtin parameters.

clear()

Clears the QosPolicy object

property default_external_unicast_locators

The collection of external locators to use for communication on user created topics.

property default_multicast_locator_list

Default list of Multicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case that it was defined with NO MulticastLocators. This is usually left empty.

property default_unicast_locator_list

Default list of Unicast Locators to be used for any Endpoint defined inside this RTPSParticipant in the case that it was defined with NO UnicastLocators. At least ONE locator should be included in this list.

easy_mode(*args)

Overload 1:

Setter for ROS 2 Easy Mode IP

Parameters:

ip (string) – IP address to set

Notes: The IP address must be an IPv4 address. If it is not, the IP address will not be set.

Return type:

int

Returns:

RETCODE_OK if the IP address is set, an specific error code otherwise: RETCODE_BAD_PARAMETER if the IP address is not an IPv4 address.


Overload 2:

Getter for ROS 2 Easy Mode IP

Return type:

string

Returns:

IP address if set, empty string otherwise

property ignore_non_matching_locators

Whether locators that don’t match with the announced locators should be kept.

property participant_id

Participant ID By default, -1.

property port

Port Parameters

property prefix

Optionally allows user to define the GuidPrefix_t

property thisown

The membership flag

21.1.1.3.47. WriterDataLifecycleQosPolicy
class fastdds.WriterDataLifecycleQosPolicy

Specifies the behavior of the DataWriter with regards to the lifecycle of the data-instances it manages. Warning: This Qos Policy will be implemented in future releases. Notes: Mutable Qos Policy

property autodispose_unregistered_instances

Controls whether a DataWriter will automatically dispose instances each time they are unregistered. The setting autodispose_unregistered_instances = TRUE indicates that unregistered instances will also be considered disposed.

By default, true.

clear()
property thisown

The membership flag

21.1.1.3.48. WriterResourceLimitsQos
class fastdds.WriterResourceLimitsQos

Qos Policy to configure the limit of the writer resources

clear()
property matched_subscriber_allocation

Matched subscribers allocation limits.

property reader_filters_allocation

Reader filters allocation limits.

property thisown

The membership flag

21.1.1.4. Status
21.1.1.4.1. BaseStatus
class fastdds.BaseStatus

A struct storing the base status

property thisown

The membership flag

property total_count

Total cumulative count

property total_count_change

Increment since the last time the status was read

21.1.1.4.2. DeadlineMissedStatus
class fastdds.DeadlineMissedStatus

A struct storing the deadline status

property last_instance_handle

Handle to the last instance missing the deadline

property thisown

The membership flag

property total_count

Total cumulative number of offered deadline periods elapsed during which a writer failed to provide data Missed deadlines accumulate, that is, each deadline period the total_count will be incremented by 1

property total_count_change

The change in total_count since the last time the listener was called or the status was read

21.1.1.4.3. IncompatibleQosStatus
class fastdds.IncompatibleQosStatus

A struct storing the requested incompatible QoS status

property last_policy_id

The id of the policy that was found to be incompatible the last time an incompatibility is detected

property policies

A list of QosPolicyCount

property thisown

The membership flag

property total_count

Total cumulative number of times the concerned writer discovered a reader for the same topic The requested QoS is incompatible with the one offered by the writer

property total_count_change

The change in total_count since the last time the listener was called or the status was read

21.1.1.4.4. InconsistentTopicStatus
21.1.1.4.5. LivelinessChangedStatus
class fastdds.LivelinessChangedStatus

A struct storing the liveliness changed status

property alive_count

The total number of currently active publishers that write the topic read by the subscriber This count increases when a newly matched publisher asserts its liveliness for the first time or when a publisher previously considered to be not alive reasserts its liveliness. The count decreases when a publisher considered alive fails to assert its liveliness and becomes not alive, whether because it was deleted normally or for some other reason

property alive_count_change

The change in the alive_count since the last time the listener was called or the status was read

property last_publication_handle

Handle to the last publisher whose change in liveliness caused this status to change

property not_alive_count

The total count of current publishers that write the topic read by the subscriber that are no longer asserting their liveliness This count increases when a publisher considered alive fails to assert its liveliness and becomes not alive for some reason other than the normal deletion of that publisher. It decreases when a previously not alive publisher either reasserts its liveliness or is deleted normally

property not_alive_count_change

The change in the not_alive_count since the last time the listener was called or the status was read

property thisown

The membership flag

21.1.1.4.6. MatchedStatus
class fastdds.MatchedStatus

A structure storing a matching status

property current_count

The number of writers currently matched to the concerned reader

property current_count_change

The change in current_count since the last time the listener was called or the status was read

property thisown

The membership flag

property total_count

Total cumulative count the concerned reader discovered a match with a writer It found a writer for the same topic with a requested QoS that is compatible with that offered by the reader

property total_count_change

The change in total_count since the last time the listener was called or the status was read

21.1.1.4.7. OfferedDeadlineMissedStatus
21.1.1.4.8. OfferedIncompatibleQosStatus
21.1.1.4.9. PublicationMatchedStatus
class fastdds.PublicationMatchedStatus

A structure storing the publication status

property last_subscription_handle

Handle to the last reader that matched the writer causing the status to change

property thisown

The membership flag

21.1.1.4.10. QosPolicyCount
class fastdds.QosPolicyCount(*args)

A struct storing the id of the incompatible QoS Policy and the number of times it fails

property count

Total number of times that the concerned writer discovered a reader for the same topic The requested QoS is incompatible with the one offered by the writer

property policy_id

The id of the policy

property thisown

The membership flag

21.1.1.4.11. QosPolicyCountSeq
21.1.1.4.12. RequestedDeadlineMissedStatus
21.1.1.4.13. RequestedIncompatibleQosStatus
21.1.1.4.14. LivelinessLostStatus
21.1.1.4.15. SampleLostStatus
21.1.1.4.16. SampleRejectedStatus
class fastdds.SampleRejectedStatus

A struct storing the sample rejected status

property last_instance_handle

Handle to the instance being updated by the last sample that was rejected.

property last_reason

Reason for rejecting the last sample rejected. If no samples have been rejected, the reason is the special value NOT_REJECTED.

property thisown

The membership flag

property total_count

Total cumulative count of samples rejected by the DataReader.

property total_count_change

The incremental number of samples rejected since the last time the listener was called or the status was read.

21.1.1.4.17. SampleRejectedStatusKind
class fastdds.NOT_REJECTED(*args: Any, **kwargs: Any)
class fastdds.REJECTED_BY_INSTANCES_LIMIT(*args: Any, **kwargs: Any)
class fastdds.REJECTED_BY_SAMPLES_LIMIT(*args: Any, **kwargs: Any)
class fastdds.REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT(*args: Any, **kwargs: Any)
21.1.1.4.18. StatusMask
class fastdds.StatusMask(*args)

StatusMask is a bitmap or bitset field.

This bitset is used to: - determine which listener functions to call - set conditions in dds::core::cond::StatusCondition - indicate status changes when calling dds::core::Entity::status_changes

static all()

Get all StatusMasks

Return type:

StatusMask

Returns:

StatusMask all

static data_available()

get the statusmask associated with dds::core::status::data_available

Return type:

StatusMask

Returns:

statusmask data_available

static data_on_readers()

Get the StatusMask associated with dds::core::status::data_on_readers

Return type:

StatusMask

Returns:

StatusMask data_on_readers

static inconsistent_topic()

Get the StatusMask associated with dds::core::status::InconsistentTopicStatus

Return type:

StatusMask

Returns:

StatusMask inconsistent_topic

is_active(status)

Checks if the status passed as parameter is 1 in the actual StatusMask :type status: StatusMask :param status: Status that need to be checked :rtype: boolean :return: true if the status is active and false if not

static liveliness_changed()

Get the StatusMask associated with dds::core::status::LivelinessChangedStatus

Return type:

StatusMask

Returns:

StatusMask liveliness_changed

static liveliness_lost()

Get the StatusMask associated with dds::core::status::LivelinessLostStatus

Return type:

StatusMask

Returns:

StatusMask liveliness_lost

static none()

Get no StatusMasks

Return type:

StatusMask

Returns:

StatusMask none

static offered_deadline_missed()

Get the StatusMask associated with dds::core::status::OfferedDeadlineMissedStatus

Return type:

StatusMask

Returns:

StatusMask offered_deadline_missed

static offered_incompatible_qos()

Get the StatusMask associated with dds::core::status::OfferedIncompatibleQosStatus

Return type:

StatusMask

Returns:

StatusMask offered_incompatible_qos

static publication_matched()

Get the statusmask associated with dds::core::status::PublicationMatchedStatus

Return type:

StatusMask

Returns:

StatusMask publication_matched

static requested_deadline_missed()

Get the StatusMask associated with dds::core::status::RequestedDeadlineMissedStatus

Return type:

StatusMask

Returns:

StatusMask requested_deadline_missed

static requested_incompatible_qos()

Get the StatusMask associated with dds::core::status::RequestedIncompatibleQosStatus

Return type:

StatusMask

Returns:

StatusMask requested_incompatible_qos

static sample_lost()

Get the StatusMask associated with dds::core::status::SampleLostStatus

Return type:

StatusMask

Returns:

StatusMask sample_lost

static sample_rejected()

Get the StatusMask associated with dds::core::status::SampleRejectedStatus

Return type:

StatusMask

Returns:

StatusMask sample_rejected

static subscription_matched()

Get the statusmask associated with dds::core::status::SubscriptionMatchedStatus

Return type:

StatusMask

Returns:

StatusMask subscription_matched

property thisown

The membership flag

21.1.1.4.19. SubscriptionMatchedStatus
class fastdds.SubscriptionMatchedStatus

A structure storing the subscription status

property last_publication_handle

Handle to the last writer that matched the reader causing the status change

property thisown

The membership flag

21.1.1.5. LoanableArray
21.1.1.6. LoanableCollection
class fastdds.LoanableCollection(*args, **kwargs)

A collection of generic opaque pointers that can receive the buffer from outside (loan).

This is an abstract class. See ‘LoanableSequence’ for details.

buffer()

Get the pointer to the elements buffer.

The returned value may be nullptr if maximum() is 0. Otherwise it is guaranteed that up to maximum() elements can be accessed.

Return type:

void

Returns:

the pointer to the elements buffer.

has_ownership()

Get the ownership flag.

Return type:

boolean

Returns:

whether the collection has ownership of the buffer.

length(*args)

Overload 1:

Get the number of elements currently accessible.

Return type:

int

Returns:

the number of elements currently accessible.


Overload 2:

Set the number of elements currently accessible.

This method tells the collection that a certain number of elements should be accessible. If the new length is greater than the current ‘maximum()’ the collection should allocate space for the new elements. If this is the case and the collection does not own the buffer (i.e. ‘has_ownership()’ is false) then no allocation will be performed, the length will remain unchanged, and false will be returned.

Parameters:

[in] – new_length New number of elements to be accessible.

Return type:

boolean

Returns:

true if the new length was correctly set.

loan(buffer, new_maximum, new_length)

Loan a buffer to the collection.

Parameters:
  • [in] – buffer pointer to the buffer to be loaned.

  • [in] – new_maximum number of allocated elements in buffer.

  • [in] – new_length number of accessible elements in buffer.

Return type:

boolean

Returns:

false if preconditions are not met.

Return type:

boolean

Returns:

true if operation succeeds.

maximum()

Get the maximum number of elements currently allocated.

Return type:

int

Returns:

the maximum number of elements currently allocated.

property thisown

The membership flag

unloan(*args)

Overload 1:

Remove the loan from the collection.

Parameters:
  • [out] – maximum number of allocated elements on the returned buffer.

  • [out] – length number of accessible elements on the returned buffer.

Return type:

void

Returns:

nullptr if preconditions are not met.

Return type:

void

Returns:

pointer to the previously loaned buffer of elements.


Overload 2:

Remove the loan from the collection.

Return type:

void

Returns:

nullptr if preconditions are not met.

Return type:

void

Returns:

pointer to the previously loaned buffer of elements.

21.1.1.7. LoanableSequence
21.1.1.8. StackAllocatedSequence

21.1.2. Domain

21.1.2.1. DomainParticipant
class fastdds.DomainParticipant(*args, **kwargs)

Class DomainParticipant used to group Publishers and Subscribers into a single working unit.

assert_liveliness()

This operation manually asserts the liveliness of the DomainParticipant. This is used in combination with the LIVELINESS QoS policy to indicate to the Service that the entity remains active.

This operation needs to only be used if the DomainParticipant contains DataWriter entities with the LIVELINESS set to MANUAL_BY_PARTICIPANT and it only affects the liveliness of those DataWriter entities. Otherwise, it has no effect.

Notes: Writing data via the write operation on a DataWriter asserts liveliness on the DataWriter itself and its DomainParticipant. Consequently the use of assert_liveliness is only needed if the application is not writing data regularly.

Return type:

int

Returns:

RETCODE_OK if the liveliness was asserted, RETCODE_ERROR otherwise.

contains_entity(a_handle, recursive=True)

This operation checks whether or not the given handle represents an Entity that was created from the DomainParticipant.

Parameters:
  • a_handle (InstanceHandle_t) – InstanceHandle of the entity to look for.

  • recursive (boolean) – The containment applies recursively. That is, it applies both to entities (TopicDescription, Publisher, or Subscriber) created directly using the DomainParticipant as well as entities created using a contained Publisher, or Subscriber as the factory, and so forth. (default: true)

Return type:

boolean

Returns:

True if entity is contained. False otherwise.

create_contentfilteredtopic(*args)

Overload 1:

Create a ContentFilteredTopic in this Participant.

Parameters:
  • name (string) – Name of the ContentFilteredTopic

  • related_topic (Topic) – Related Topic to being subscribed

  • filter_expression (string) – Logic expression to create filter

  • expression_parameters (std::vector< std::string,std::allocator< std::string > >) – Parameters to filter content

Return type:

ContentFilteredTopic

Returns:

Pointer to the created ContentFilteredTopic.

Return type:

ContentFilteredTopic

Returns:

nullptr if related_topic does not belong to this participant.

Return type:

ContentFilteredTopic

Returns:

nullptr if a topic with the specified name has already been created.

Return type:

ContentFilteredTopic

Returns:

nullptr if a filter cannot be created with the specified filter_expression and expression_parameters.


Overload 2:

Create a ContentFilteredTopic in this Participant using a custom filter.

Parameters:
  • name (string) – Name of the ContentFilteredTopic

  • related_topic (Topic) – Related Topic to being subscribed

  • filter_expression (string) – Logic expression to create filter

  • expression_parameters (std::vector< std::string,std::allocator< std::string > >) – Parameters to filter content

  • filter_class_name (string) – Name of the filter class to use

Return type:

ContentFilteredTopic

Returns:

Pointer to the created ContentFilteredTopic.

Return type:

ContentFilteredTopic

Returns:

nullptr if related_topic does not belong to this participant.

Return type:

ContentFilteredTopic

Returns:

nullptr if a topic with the specified name has already been created.

Return type:

ContentFilteredTopic

Returns:

nullptr if a filter cannot be created with the specified filter_expression and expression_parameters.

Return type:

ContentFilteredTopic

Returns:

nullptr if the specified filter_class_name has not been registered.

create_multitopic(name, type_name, subscription_expression, expression_parameters)

Create a MultiTopic in this Participant.

Parameters:
  • name (string) – Name of the MultiTopic

  • type_name (string) – Result type of the MultiTopic

  • subscription_expression (string) – Logic expression to combine filter

  • expression_parameters (std::vector< std::string,std::allocator< std::string > >) – Parameters to subscription content

Return type:

eprosima::fastdds::dds::MultiTopic

Returns:

Pointer to the created ContentFilteredTopic, nullptr in error case

create_publisher(*args)

Create a Publisher in this Participant.

Parameters:
  • qos (PublisherQos) – QoS of the Publisher.

  • listener (PublisherListener) – Pointer to the listener (default: nullptr)

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all)

Return type:

Publisher

Returns:

Pointer to the created Publisher.

create_publisher_with_profile(*args)

Create a Publisher in this Participant.

Parameters:
  • profile_name (string) – Publisher profile name.

  • listener (PublisherListener) – Pointer to the listener (default: nullptr)

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all)

Return type:

Publisher

Returns:

Pointer to the created Publisher.

create_service(service_name, service_type_name)

Create a RPC service.

Parameters:
  • service_name (string) – Name of the service.

  • service_type_name (string) – Type name of the service (Request & reply types)

Return type:

eprosima::fastdds::dds::rpc::Service

Returns:

Pointer to the created service. nullptr in error case.

create_service_replier(service, replier_qos)

Create a RPC Replier in a given Service. It will override the current service’s replier

Parameters:
  • service (eprosima::fastdds::dds::rpc::Service) – Pointer to a service object where the Replier will be created.

  • replier_qos (ReplierQos) – QoS of the replier.

Return type:

eprosima::fastdds::dds::rpc::Replier

Returns:

Pointer to the created replier. nullptr in error case.

create_service_requester(service, requester_qos)

Create a RPC Requester in a given Service.

Parameters:
  • service (eprosima::fastdds::dds::rpc::Service) – Pointer to a service object where the requester will be created.

  • requester_qos (RequesterQos) – QoS of the requester.

Return type:

eprosima::fastdds::dds::rpc::Requester

Returns:

Pointer to the created requester. nullptr in error case.

create_subscriber(*args)

Create a Subscriber in this Participant.

Parameters:
  • qos (SubscriberQos) – QoS of the Subscriber.

  • listener (SubscriberListener) – Pointer to the listener (default: nullptr)

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all)

Return type:

Subscriber

Returns:

Pointer to the created Subscriber.

create_subscriber_with_profile(*args)

Create a Subscriber in this Participant.

Parameters:
  • profile_name (string) – Subscriber profile name.

  • listener (SubscriberListener) – Pointer to the listener (default: nullptr)

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all)

Return type:

Subscriber

Returns:

Pointer to the created Subscriber.

create_topic(*args)

Create a Topic in this Participant.

Parameters:
  • topic_name (string) – Name of the Topic.

  • type_name (string) – Data type of the Topic.

  • qos (TopicQos) – QoS of the Topic.

  • listener (TopicListener) – Pointer to the listener (default: nullptr)

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all)

Return type:

Topic

Returns:

Pointer to the created Topic.

create_topic_with_profile(*args)

Create a Topic in this Participant.

Parameters:
  • topic_name (string) – Name of the Topic.

  • type_name (string) – Data type of the Topic.

  • profile_name (string) – Topic profile name.

  • listener (TopicListener) – Pointer to the listener (default: nullptr)

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all)

Return type:

Topic

Returns:

Pointer to the created Topic.

delete_contained_entities()

Deletes all the entities that were created by means of the “create” methods

Return type:

int

Returns:

RETURN_OK code if everything correct, error code otherwise

delete_contentfilteredtopic(a_contentfilteredtopic)

Deletes an existing ContentFilteredTopic.

Parameters:

a_contentfilteredtopic (ContentFilteredTopic) – ContentFilteredTopic to be deleted

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the topic passed is a nullptr, RETCODE_PRECONDITION_NOT_MET if the topic does not belong to this participant or if it is referenced by any entity and RETCODE_OK if the ContentFilteredTopic was deleted.

delete_multitopic(a_multitopic)

Deletes an existing MultiTopic.

Parameters:

a_multitopic (eprosima::fastdds::dds::MultiTopic) – MultiTopic to be deleted

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the topic passed is a nullptr, RETCODE_PRECONDITION_NOT_MET if the topic does not belong to this participant or if it is referenced by any entity and RETCODE_OK if the Topic was deleted.

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

delete_publisher(publisher)

Deletes an existing Publisher.

Parameters:

publisher (Publisher) – to be deleted.

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if the publisher does not belong to this participant or if it has active DataWriters, RETCODE_OK if it is correctly deleted and RETCODE_ERROR otherwise.

delete_service(service)

Delete a registered RPC service

Parameters:

service (eprosima::fastdds::dds::rpc::Service) – Pointer to the service to be deleted.

Return type:

int

Returns:

RETCODE_OK if the service was deleted, or an specific error code otherwise.

delete_service_replier(service_name, replier)

Deletes an existing RPC Replier

Parameters:
  • service_name (string) – Name of the service where the replier is created.

  • replier (eprosima::fastdds::dds::rpc::Replier) – Pointer to the replier to be deleted.

Return type:

int

Returns:

RETCODE_OK if the replier was deleted, or an specific error code otherwise.

delete_service_requester(service_name, requester)

Deletes an existing RPC Requester

Parameters:
  • service_name (string) – Name of the service where the requester is created.

  • requester (eprosima::fastdds::dds::rpc::Requester) – Pointer to the requester to be deleted.

Return type:

int

Returns:

RETCODE_OK if the requester was deleted, or an specific error code otherwise.

delete_subscriber(subscriber)

Deletes an existing Subscriber.

Parameters:

subscriber (Subscriber) – to be deleted.

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if the subscriber does not belong to this participant or if it has active DataReaders, RETCODE_OK if it is correctly deleted and RETCODE_ERROR otherwise.

delete_topic(topic)

Deletes an existing Topic.

Parameters:

topic (Topic) – to be deleted.

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the topic passed is a nullptr, RETCODE_PRECONDITION_NOT_MET if the topic does not belong to this participant or if it is referenced by any entity and RETCODE_OK if the Topic was deleted.

enable()

This operation enables the DomainParticipant

Return type:

int

Returns:

RETCODE_OK

find_service(service_name)

Find a RPC service by name

Parameters:

service_name (string) – Name of the service to search for.

Return type:

eprosima::fastdds::dds::rpc::Service

Returns:

Pointer to the service object if found, nullptr if not found.

find_service_type(service_type_name)

This method gives access to a registered service type based on its name.

Parameters:

service_type_name (string) – Name of the type

Return type:

eprosima::fastdds::dds::rpc::ServiceTypeSupport

Returns:

ServiceTypeSupport corresponding to the service_type_name

find_topic(topic_name, timeout)

Gives access to an existing (or ready to exist) enabled Topic. It should be noted that the returned Topic is a local object that acts as a proxy to designate the global concept of topic. Topics obtained by means of find_topic, must also be deleted by means of delete_topic so that the local resources can be released. If a Topic is obtained multiple times by means of find_topic or create_topic, it must also be deleted that same number of times using delete_topic.

Parameters:
  • topic_name (string) – Topic name

  • timeout (Duration_t) – Maximum time to wait for the Topic

Return type:

Topic

Returns:

Pointer to the existing Topic, nullptr in case of error or timeout

find_type(type_name)

This method gives access to a registered type based on its name.

Parameters:

type_name (string) – Name of the type

Return type:

TypeSupport

Returns:

TypeSupport corresponding to the type_name

get_builtin_subscriber()

Allows access to the builtin Subscriber.

Return type:

Subscriber

Returns:

Pointer to the builtin Subscriber, nullptr in error case

get_current_time(current_time)

This operation returns the current value of the time that the service uses to time-stamp data-writes and to set the reception-timestamp for the data-updates it receives.

Parameters:

current_time (Time_t) – Time_t reference where the current time is returned

Return type:

int

Returns:

RETCODE_OK

get_default_publisher_qos(*args)

Overload 1:

This operation retrieves the default value of the Publisher QoS, that is, the QoS policies which will be used for newly created Publisher entities in the case where the QoS policies are defaulted in the create_publisher operation.

The values retrieved get_default_publisher_qos will match the set of values specified on the last successful call to set_default_publisher_qos, or else, if the call was never made, the default values.

Return type:

PublisherQos

Returns:

Current default publisher qos.


Overload 2:

This operation retrieves the default value of the Publisher QoS, that is, the QoS policies which will be used for newly created Publisher entities in the case where the QoS policies are defaulted in the create_publisher operation.

The values retrieved get_default_publisher_qos will match the set of values specified on the last successful call to set_default_publisher_qos, or else, if the call was never made, the default values.

Parameters:

qos (PublisherQos) – PublisherQos reference where the default_publisher_qos is returned

Return type:

int

Returns:

RETCODE_OK

get_default_publisher_qos_from_xml(xml, qos)

Fills the ‘PublisherQos’ with the default publisher profile found in the provided XML (if there is).

Notes: This method does not update the default publisher qos (returned by get_default_publisher_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (PublisherQos) – ‘PublisherQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_default_replier_qos_from_xml(xml, qos)

Fills the ‘ReplierQos’ with the default replier profile found in the provided XML (if there is).

Notes: This method does not update the default replier qos.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (ReplierQos) – ‘ReplierQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_default_requester_qos_from_xml(xml, qos)

Fills the ‘RequesterQos’ with the default requester profile found in the provided XML (if there is).

Notes: This method does not update the default requester qos.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (RequesterQos) – ‘RequesterQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_default_subscriber_qos(*args)

Overload 1:

This operation retrieves the default value of the Subscriber QoS, that is, the QoS policies which will be used for newly created Subscriber entities in the case where the QoS policies are defaulted in the create_subscriber operation.

The values retrieved get_default_subscriber_qos will match the set of values specified on the last successful call to set_default_subscriber_qos, or else, if the call was never made, the default values.

Return type:

SubscriberQos

Returns:

Current default subscriber qos.


Overload 2:

This operation retrieves the default value of the Subscriber QoS, that is, the QoS policies which will be used for newly created Subscriber entities in the case where the QoS policies are defaulted in the create_subscriber operation.

The values retrieved get_default_subscriber_qos will match the set of values specified on the last successful call to set_default_subscriber_qos, or else, if the call was never made, the default values.

Parameters:

qos (SubscriberQos) – SubscriberQos reference where the default_subscriber_qos is returned

Return type:

int

Returns:

RETCODE_OK

get_default_subscriber_qos_from_xml(xml, qos)

Fills the ‘SubscriberQos’ with the default subscriber profile found in the provided XML (if there is).

Notes: This method does not update the default subscriber qos (returned by get_default_subscriber_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (SubscriberQos) – ‘SubscriberQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_default_topic_qos(*args)

Overload 1:

This operation retrieves the default value of the Topic QoS, that is, the QoS policies that will be used for newly created Topic entities in the case where the QoS policies are defaulted in the create_topic operation.

The values retrieved get_default_topic_qos will match the set of values specified on the last successful call to set_default_topic_qos, or else, TOPIC_QOS_DEFAULT if the call was never made.

Return type:

TopicQos

Returns:

Current default topic qos.


Overload 2:

This operation retrieves the default value of the Topic QoS, that is, the QoS policies that will be used for newly created Topic entities in the case where the QoS policies are defaulted in the create_topic operation.

The values retrieved get_default_topic_qos will match the set of values specified on the last successful call to set_default_topic_qos, or else, TOPIC_QOS_DEFAULT if the call was never made.

Parameters:

qos (TopicQos) – TopicQos reference where the default_topic_qos is returned

Return type:

int

Returns:

RETCODE_OK

get_default_topic_qos_from_xml(*args)

Overload 1:

Fills the ‘TopicQos’ with the default topic profile found in the provided XML (if there is).

Notes: This method does not update the default topic qos (returned by get_default_topic_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (TopicQos) – ‘TopicQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘TopicQos’ with the default topic profile found in the provided XML (if there is), and also its corresponding topic and data type names (if specified).

Notes: This method does not update the default topic qos (returned by get_default_topic_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (TopicQos) – ‘TopicQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

  • topic_data_type (string) – String where the name of the topic data type associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_discovered_participant_data(participant_data, participant_handle)

Retrieves the DomainParticipant data of a discovered not ignored participant.

Parameters:
  • [out] – participant_data Reference to the ParticipantBuiltinTopicData object to return the data

  • participant_handle (InstanceHandle_t) – InstanceHandle of DomainParticipant to retrieve the data from

Return type:

int

Returns:

RETCODE_OK if everything correct, PRECONDITION_NOT_MET if participant does not exist

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_discovered_participants(participant_handles)

Retrieves the list of DomainParticipants that have been discovered in the domain and are not “ignored”.

Parameters:

[out] – participant_handles Reference to the vector where discovered participants will be returned

Return type:

int

Returns:

RETCODE_OK if everything correct, error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_discovered_topic_data(topic_data, topic_handle)

Retrieves the Topic data of a discovered not ignored topic.

Parameters:
  • [out] – topic_data Reference to the TopicBuiltinTopicData object to return the data

  • topic_handle (InstanceHandle_t) – InstanceHandle of Topic to retrieve the data from

Return type:

int

Returns:

RETCODE_OK if everything correct, PRECONDITION_NOT_MET if topic does not exist

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_discovered_topics(topic_handles)

Retrieves the list of topics that have been discovered in the domain and are not “ignored”.

Parameters:

[out] – topic_handles Reference to the vector where discovered topics will be returned

Return type:

int

Returns:

RETCODE_OK if everything correct, error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_domain_id()

This operation retrieves the domain_id used to create the DomainParticipant. The domain_id identifies the DDS domain to which the DomainParticipant belongs.

Return type:

int

Returns:

The Participant’s domain_id

get_instance_handle()

Returns the DomainParticipant’s handle.

Return type:

InstanceHandle_t

Returns:

InstanceHandle of this DomainParticipant.

get_listener()

Allows accessing the DomainParticipantListener.

Return type:

DomainParticipantListener

Returns:

DomainParticipantListener pointer

get_participant_names()

Getter for the participant names

Return type:

std::vector< std::string,std::allocator< std::string > >

Returns:

Vector with the names

get_publisher_qos_from_profile(profile_name, qos)

Fills the ‘PublisherQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – Publisher profile name.

  • qos (PublisherQos) – ‘PublisherQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_publisher_qos_from_xml(*args)

Overload 1:

Fills the ‘PublisherQos’ with the first publisher profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (PublisherQos) – ‘PublisherQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘PublisherQos’ with the publisher profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (PublisherQos) – ‘PublisherQos’ object where the qos is returned.

  • profile_name (string) – Publisher profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_qos(*args)

Overload 1:

This operation returns the value of the DomainParticipant QoS policies

Parameters:

qos (DomainParticipantQos) – DomainParticipantQos reference where the qos is going to be returned

Return type:

int

Returns:

RETCODE_OK


Overload 2:

This operation returns the value of the DomainParticipant QoS policies

Return type:

DomainParticipantQos

Returns:

A reference to the DomainParticipantQos

get_replier_qos_from_profile(profile_name, qos)

Fills the ‘ReplierQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – Replier profile name.

  • qos (ReplierQos) – ‘ReplierQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_replier_qos_from_xml(*args)

Overload 1:

Fills the ‘ReplierQos’ with the first replier profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (ReplierQos) – ‘ReplierQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘ReplierQos’ with the replier profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (ReplierQos) – ‘ReplierQos’ object where the qos is returned.

  • profile_name (string) – Replier profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_requester_qos_from_profile(profile_name, qos)

Fills the ‘RequesterQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – Requester profile name.

  • qos (RequesterQos) – ‘RequesterQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_requester_qos_from_xml(*args)

Overload 1:

Fills the ‘RequesterQos’ with the first requester profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (RequesterQos) – ‘RequesterQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘RequesterQos’ with the requester profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (RequesterQos) – ‘RequesterQos’ object where the qos is returned.

  • profile_name (string) – Requester profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_subscriber_qos_from_profile(profile_name, qos)

Fills the ‘SubscriberQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – Subscriber profile name.

  • qos (SubscriberQos) – ‘SubscriberQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_subscriber_qos_from_xml(*args)

Overload 1:

Fills the ‘SubscriberQos’ with the first subscriber profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (SubscriberQos) – ‘SubscriberQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘SubscriberQos’ with the subscriber profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (SubscriberQos) – ‘SubscriberQos’ object where the qos is returned.

  • profile_name (string) – Subscriber profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_topic_qos_from_profile(*args)

Overload 1:

Fills the ‘TopicQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – Topic profile name.

  • qos (TopicQos) – ‘TopicQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘TopicQos’ with the values of the XML profile, and also its corresponding topic and data type names (if specified).

Parameters:
  • profile_name (string) – Topic profile name.

  • qos (TopicQos) – ‘TopicQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

  • topic_data_type (string) – String where the name of the topic data type associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_topic_qos_from_xml(*args)

Overload 1:

Fills the ‘TopicQos’ with the first topic profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (TopicQos) – ‘TopicQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘TopicQos’ with the first topic profile found in the provided XML, and also its corresponding topic and data type names (if specified).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (TopicQos) – ‘TopicQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

  • topic_data_type (string) – String where the name of the topic data type associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 3:

Fills the ‘TopicQos’ with the topic profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (TopicQos) – ‘TopicQos’ object where the qos is returned.

  • profile_name (string) – Topic profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 4:

Fills the ‘TopicQos’ with the topic profile with profile_name to be found in the provided XML, and also its corresponding topic and data type names (if specified).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (TopicQos) – ‘TopicQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

  • topic_data_type (string) – String where the name of the topic data type associated to this profile is returned (if specified).

  • profile_name (string) – Topic profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

guid()

Getter for the Participant GUID

Return type:

GUID_t

Returns:

A reference to the GUID

ignore_participant(handle)

Locally ignore a remote domain participant.

Notes: This action is not reversible.

Parameters:

handle (InstanceHandle_t) – Identifier of the remote participant to ignore

Return type:

int

Returns:

RETURN_OK code if everything correct, RETCODE_BAD_PARAMENTER otherwise

ignore_publication(handle)

Locally ignore a remote datawriter.

Notes: This action is not reversible.

Parameters:

handle (InstanceHandle_t) – Identifier of the datawriter to ignore

Return type:

int

Returns:

RETURN_OK code if everything correct, error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

ignore_subscription(handle)

Locally ignore a remote datareader.

Notes: This action is not reversible.

Parameters:

handle (InstanceHandle_t) – Identifier of the datareader to ignore

Return type:

int

Returns:

RETURN_OK code if everything correct, error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

ignore_topic(handle)

Locally ignore a topic.

Notes: This action is not reversible.

Parameters:

handle (InstanceHandle_t) – Identifier of the topic to ignore

Return type:

int

Returns:

RETURN_OK code if everything correct, error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

lookup_content_filter_factory(filter_class_name)

Lookup a custom content filter factory previously registered with register_content_filter_factory.

Parameters:

filter_class_name (string) – Name of the filter class. Cannot be nullptr.

Return type:

IContentFilterFactory

Returns:

nullptr if the given filter_class_name has not been previously registered on this DomainParticipant. Otherwise, the content filter factory previously registered with the given filter_class_name.

lookup_topicdescription(topic_name)

Looks up an existing, locally created ‘TopicDescription’, based on its name. May be called on a disabled participant.

Parameters:

topic_name (string) – Name of the ‘TopicDescription’ to search for.

Return type:

TopicDescription

Returns:

Pointer to the topic description, if it has been created locally. Otherwise, nullptr is returned.

Remarks: UNSAFE. It is unsafe to lookup a topic description while another thread is creating a topic.

new_remote_endpoint_discovered(partguid, userId, kind)

This method can be used when using a StaticEndpointDiscovery mechanism different that the one included in Fast DDS, for example when communicating with other implementations. It indicates the Participant that an Endpoint from the XML has been discovered and should be activated.

Parameters:
  • partguid (GUID_t) – Participant GUID_t.

  • userId (int) – User defined ID as shown in the XML file.

  • kind (int) – EndpointKind (WRITER or READER)

Return type:

boolean

Returns:

True if correctly found and activated.

register_content_filter_factory(filter_class_name, filter_factory)

Register a custom content filter factory, which can be used to create a ContentFilteredTopic.

DDS specifies a SQL-like content filter to be used by content filtered topics. If this filter does not meet your filtering requirements, you can register a custom filter factory.

To use a custom filter, a factory for it must be registered in the following places:

  • In any application that uses the custom filter factory to create a ContentFilteredTopic and the corresponding DataReader.

  • In each application that writes the data to the applications mentioned above.

For example, suppose Application A on the subscription side creates a Topic named X and a ContentFilteredTopic named filteredX (and a corresponding DataReader), using a previously registered content filter factory, myFilterFactory. With only that, you will have filtering at the subscription side. If you also want to perform filtering in any application that publishes Topic X, then you also need to register the same definition of the ContentFilterFactory myFilterFactory in that application.

Each filter_class_name can only be used to register a content filter factory once per DomainParticipant.

Parameters:
  • filter_class_name (string) – Name of the filter class. Cannot be nullptr, must not exceed 255 characters, and must be unique within this DomainParticipant.

  • filter_factory (IContentFilterFactory) – Factory of content filters to be registered. Cannot be nullptr.

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if any parameter is nullptr, or the filter_class_name exceeds 255 characters.

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if the filter_class_name has been already registered.

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if filter_class_name is FASTDDS_SQLFILTER_NAME.

Return type:

int

Returns:

RETCODE_OK if the filter is correctly registered.

register_service_type(service_type, service_type_name)

Register a service type in this participant.

Parameters:
  • service_type (eprosima::fastdds::dds::rpc::ServiceTypeSupport) – ServiceTypeSupport.

  • service_type_name (string) – The name that will be used to identify the service type.

Return type:

int

Returns:

RETCODE_OK if it is correctly registered. Error code otherwise.

register_type(*args)

Overload 1:

Register a type in this participant.

Parameters:
  • type (TypeSupport) – TypeSupport.

  • type_name (string) – The name that will be used to identify the Type.

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the size of the name is 0, RERCODE_PRECONDITION_NOT_MET if there is another TypeSupport with the same name and RETCODE_OK if it is correctly registered.


Overload 2:

Register a type in this participant.

Parameters:

type (TypeSupport) – TypeSupport.

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the size of the name is 0, RERCODE_PRECONDITION_NOT_MET if there is another TypeSupport with the same name and RETCODE_OK if it is correctly registered.

set_default_publisher_qos(qos)

This operation sets a default value of the Publisher QoS policies which will be used for newly created Publisher entities in the case where the QoS policies are defaulted in the create_publisher operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return false.

The special value PUBLISHER_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_publisher_qos operation had never been called.

Parameters:

qos (PublisherQos) – PublisherQos to be set

Return type:

int

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

set_default_subscriber_qos(qos)

This operation sets a default value of the Subscriber QoS policies that will be used for newly created Subscriber entities in the case where the QoS policies are defaulted in the create_subscriber operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return false.

The special value SUBSCRIBER_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_subscriber_qos operation had never been called.

Parameters:

qos (SubscriberQos) – SubscriberQos to be set

Return type:

int

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

set_default_topic_qos(qos)

This operation sets a default value of the Topic QoS policies which will be used for newly created Topic entities in the case where the QoS policies are defaulted in the create_topic operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return INCONSISTENT_POLICY.

The special value TOPIC_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_topic_qos operation had never been called.

Parameters:

qos (TopicQos) – TopicQos to be set

Return type:

int

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

set_listener(*args)

Overload 1:

Modifies the DomainParticipantListener, sets the mask to StatusMask::all()

Parameters:

listener (DomainParticipantListener) – new value for the DomainParticipantListener

Return type:

int

Returns:

RETCODE_OK


Overload 2:

Modifies the DomainParticipantListener.

Parameters:
Return type:

int

Returns:

RETCODE_OK

set_qos(qos)

This operation sets the value of the DomainParticipant QoS policies.

Parameters:

qos (DomainParticipantQos) – DomainParticipantQos to be set

Return type:

int

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

property thisown

The membership flag

unregister_content_filter_factory(filter_class_name)

Unregister a custom content filter factory previously registered with register_content_filter_factory.

A filter_class_name can be unregistered only if it has been previously registered to the DomainParticipant with register_content_filter_factory.

The unregistration of filter is not allowed if there are any existing ContentFilteredTopic objects that are using the filter.

If there is any existing discovered DataReader with the same filter_class_name, filtering on the writer side will be stopped, but this operation will not fail.

Parameters:

filter_class_name (string) – Name of the filter class. Cannot be nullptr.

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the filter_class_name is nullptr.

Return type:

int

Returns:

RERCODE_PRECONDITION_NOT_MET if the filter_class_name has not been previously registered.

Return type:

int

Returns:

RERCODE_PRECONDITION_NOT_MET if there is any ContentFilteredTopic referencing the filter.

Return type:

int

Returns:

RETCODE_OK if the filter is correctly unregistered.

unregister_service_type(service_type_name)

Unregister a service type in this participant.

Parameters:

service_type_name (string) – Name of the type

Return type:

int

Returns:

RETCODE_OK if it is correctly unregistered. Error code otherwise.

unregister_type(typeName)

Unregister a type in this participant.

Parameters:

typeName (string) – Name of the type

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the size of the name is 0, RERCODE_PRECONDITION_NOT_MET if there are entities using that TypeSupport and RETCODE_OK if it is correctly unregistered.

21.1.2.2. DomainParticipantFactory
class fastdds.DomainParticipantFactory(*args, **kwargs)

Class DomainParticipantFactory

check_xml_static_discovery(xml_file)

Check the validity of the provided static discovery XML file

Parameters:

xml_file (string) – xml file path

Return type:

int

Returns:

RETCODE_OK if the validation is successful, RETCODE_ERROR otherwise.

create_participant(*args)

Overload 1:

Create a Participant.

Parameters:
Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)


Overload 2:

Create a Participant.

Parameters:
  • extended_qos (DomainParticipantExtendedQos) – DomainParticipantExtendedQos Reference.

  • listener (DomainParticipantListener) – DomainParticipantListener Pointer (default: nullptr)

  • mask (StatusMask) – StatusMask Reference (default: all)

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)


Overload 3:

Create a Participant.

Parameters:
  • extended_qos (DomainParticipantExtendedQos) – DomainParticipantExtendedQos Reference.

  • listener (DomainParticipantListener) – DomainParticipantListener Pointer (default: nullptr)

  • mask – StatusMask Reference (default: all)

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)


Overload 4:

Create a Participant.

Parameters:
  • extended_qos (DomainParticipantExtendedQos) – DomainParticipantExtendedQos Reference.

  • listener – DomainParticipantListener Pointer (default: nullptr)

  • mask – StatusMask Reference (default: all)

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)

create_participant_with_default_profile(*args)

Overload 1:

Create a Participant with default domain id and qos.

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)


Overload 2:

Create a Participant with default domain id and qos.

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)

Parameters:
create_participant_with_profile(*args)

Overload 1:

Create a Participant.

Parameters:
  • domain_id (int) – Domain Id.

  • profile_name (string) – Participant profile name.

  • listener (DomainParticipantListener) – DomainParticipantListener Pointer (default: nullptr)

  • mask (StatusMask) – StatusMask Reference (default: all)

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)


Overload 2:

Create a Participant.

Parameters:
  • profile_name (string) – Participant profile name.

  • listener (DomainParticipantListener) – DomainParticipantListener Pointer (default: nullptr)

  • mask (StatusMask) – StatusMask Reference (default: all)

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)


Overload 3:

Create a Participant.

Parameters:
  • profile_name (string) – Participant profile name.

  • listener (DomainParticipantListener) – DomainParticipantListener Pointer (default: nullptr)

  • mask – StatusMask Reference (default: all)

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)


Overload 4:

Create a Participant.

Parameters:
  • profile_name (string) – Participant profile name.

  • listener – DomainParticipantListener Pointer (default: nullptr)

  • mask – StatusMask Reference (default: all)

Return type:

DomainParticipant

Returns:

DomainParticipant pointer. (nullptr if not created.)

delete_participant(part)

Remove a Participant and all associated publishers and subscribers.

Parameters:

part (DomainParticipant) – Pointer to the participant.

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if the participant has active entities, RETCODE_OK if the participant is correctly deleted and RETCODE_ERROR otherwise.

get_default_participant_extended_qos_from_xml(xml, extended_qos)

Fills the ‘DomainParticipantExtendedQos’ with the default DomainParticipant profile found in the provided XML (if there is).

Notes: This method does not update the default participant extended qos.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the extended_qos structure.

  • extended_qos (DomainParticipantExtendedQos) – ‘DomainParticipantExtendedQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_default_participant_qos(*args)

Overload 1:

This operation retrieves the default value of the DomainParticipant QoS, that is, the QoS policies which will be used for newly created DomainParticipant entities in the case where the QoS policies are defaulted in the create_participant operation. The values retrieved get_default_participant_qos will match the set of values specified on the last successful call to set_default_participant_qos, or else, if the call was never made, the default values.

Parameters:

qos (DomainParticipantQos) – DomainParticipantQos where the qos is returned

Return type:

int

Returns:

RETCODE_OK


Overload 2:

This operation retrieves the default value of the DomainParticipant QoS, that is, the QoS policies which will be used for newly created DomainParticipant entities in the case where the QoS policies are defaulted in the create_participant operation. The values retrieved get_default_participant_qos will match the set of values specified on the last successful call to set_default_participant_qos, or else, if the call was never made, the default values.

Return type:

DomainParticipantQos

Returns:

A reference to the default DomainParticipantQos

get_default_participant_qos_from_xml(xml, qos)

Fills the ‘DomainParticipantQos’ with the default DomainParticipant profile found in the provided XML (if there is).

Notes: This method does not update the default participant qos (returned by get_default_participant_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DomainParticipantQos) – ‘DomainParticipantQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

static get_instance()

Returns the DomainParticipantFactory singleton instance.

Return type:

DomainParticipantFactory

Returns:

A raw pointer to the DomainParticipantFactory singleton instance.

get_library_settings(library_settings)

This operation returns the value of the DomainParticipant library settings.

Parameters:

library_settings (LibrarySettings) – LibrarySettings reference where the settings are returned.

Return type:

int

Returns:

RETCODE_OK

get_participant_extended_qos_from_default_profile(extended_qos)

Fills the ‘DomainParticipantExtendedQos’ with the values of the default XML profile.

Parameters:

extended_qos (DomainParticipantExtendedQos) – ‘DomainParticipantExtendedQos’ object where the domain and qos are returned.

Return type:

int

Returns:

RETCODE_OK

get_participant_extended_qos_from_profile(profile_name, extended_qos)

Fills the ‘DomainParticipantExtendedQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – DomainParticipant profile name.

  • extended_qos (DomainParticipantExtendedQos) – DomainParticipantExtendedQos object where the domain and qos are returned.

Return type:

int

Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

get_participant_extended_qos_from_xml(*args)

Overload 1:

Fills the ‘DomainParticipantExtendedQos’ with the first DomainParticipant profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the extended_qos structure.

  • extended_qos (DomainParticipantExtendedQos) – ‘DomainParticipantExtendedQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘DomainParticipantExtendedQos’ with the DomainParticipant profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the extended_qos structure.

  • extended_qos (DomainParticipantExtendedQos) – ‘DomainParticipantExtendedQos’ object where the qos is returned.

  • profile_name (string) – DomainParticipant profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_participant_qos_from_profile(profile_name, qos)

Fills the ‘DomainParticipantQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – DomainParticipant profile name.

  • qos (DomainParticipantQos) – ‘DomainParticipantQos’ object where the qos is returned.

Return type:

int

Returns:

RETCODE_OK if the profile exists. RETCODE_BAD_PARAMETER otherwise.

get_participant_qos_from_xml(*args)

Overload 1:

Fills the ‘DomainParticipantQos’ with the first DomainParticipant profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DomainParticipantQos) – ‘DomainParticipantQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘DomainParticipantQos’ with the DomainParticipant profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DomainParticipantQos) – ‘DomainParticipantQos’ object where the qos is returned.

  • profile_name (string) – DomainParticipant profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_qos(qos)

This operation returns the value of the DomainParticipantFactory QoS policies.

Parameters:

qos (DomainParticipantFactoryQos) – DomaParticipantFactoryQos reference where the qos is returned

Return type:

int

Returns:

RETCODE_OK

static get_shared_instance()

Returns the DomainParticipantFactory singleton instance.

Return type:

std::shared_ptr< eprosima::fastdds::dds::DomainParticipantFactory >

Returns:

A shared pointer to the DomainParticipantFactory singleton instance.

load_XML_profiles_file(xml_profile_file)

Load profiles from XML file.

Parameters:

xml_profile_file (string) – XML profile file.

Return type:

int

Returns:

RETCODE_OK if it is correctly loaded, RETCODE_ERROR otherwise.

load_XML_profiles_string(data, length)

Load profiles from XML string.

Parameters:
  • data (string) – buffer containing xml data.

  • length (int) – length of data

Return type:

int

Returns:

RETCODE_OK if it is correctly loaded, RETCODE_ERROR otherwise.

load_profiles()

Load profiles from default XML file.

Return type:

int

Returns:

RETCODE_OK

lookup_participant(domain_id)

This operation retrieves a previously created DomainParticipant belonging to specified domain_id. If no such DomainParticipant exists, the operation will return ‘nullptr’. If multiple DomainParticipant entities belonging to that domain_id exist, then the operation will return one of them. It is not specified which one.

Parameters:

domain_id (int)

Return type:

DomainParticipant

Returns:

previously created DomainParticipant within the specified domain

lookup_participants(domain_id)

Returns all participants that belongs to the specified domain_id.

Parameters:

domain_id (int)

Return type:

DomainParticipantVector

Returns:

previously created DomainParticipants within the specified domain

set_default_participant_qos(qos)

This operation sets a default value of the DomainParticipant QoS policies which will be used for newly created DomainParticipant entities in the case where the QoS policies are defaulted in the create_participant operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return INCONSISTENT_POLICY.

The special value PARTICIPANT_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_participant_qos operation had never been called.

Parameters:

qos (DomainParticipantQos) – DomainParticipantQos to be set

Return type:

int

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

set_library_settings(library_settings)

This operation sets the library settings.

Library settings must be set before enabling the DomainParticipants. Otherwise, failure of the setting operation is expected.

Parameters:

library_settings (LibrarySettings) – LibrarySettings to be set.

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if any DomainParticipant is already enabled. RETCODE_OK otherwise.

set_qos(qos)

This operation sets the value of the DomainParticipantFactory QoS policies. These policies control the behavior of the object a factory for entities.

Note that despite having QoS, the DomainParticipantFactory is not an Entity.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return INCONSISTENT_POLICY.

Parameters:

qos (DomainParticipantFactoryQos) – DomainParticipantFactoryQos to be set.

Return type:

int

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

property thisown

The membership flag

type_object_registry()

Return the TypeObjectRegistry member to access the public API.

Return type:

eprosima::fastdds::dds::xtypes::ITypeObjectRegistry

Returns:

const xtypes::TypeObjectRegistry reference.

21.1.2.3. DomainParticipantFactoryQos
class fastdds.DomainParticipantFactoryQos

Class DomainParticipantFactoryQos, contains all the possible Qos that can be set for a determined participant. Please consult each of them to check for implementation details and default values.

entity_factory(*args)

Overload 1:

Getter for EntityFactoryQosPolicy :rtype: EntityFactoryQosPolicy :return: EntityFactoryQosPolicy reference


Overload 2:

Getter for EntityFactoryQosPolicy :rtype: EntityFactoryQosPolicy :return: EntityFactoryQosPolicy reference


Overload 3:

Setter for EntityFactoryQosPolicy :type entity_factory: EntityFactoryQosPolicy :param entity_factory: EntityFactoryQosPolicy

file_watch_threads(*args)

Overload 1:

Getter for file watch related ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 2:

Getter for file watch related ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 3:

Setter for the file watch related ThreadSettings

Parameters:

value (ThreadSettings) – New ThreadSettings to be set

shm_watchdog_thread(*args)

Overload 1:

Getter for SHM watchdog ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 2:

Getter for SHM watchdog ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 3:

Setter for the SHM watchdog ThreadSettings

Parameters:

value (ThreadSettings) – New ThreadSettings to be set

property thisown

The membership flag

21.1.2.4. DomainParticipantListener
class fastdds.DomainParticipantListener

Class DomainParticipantListener, overrides behaviour towards certain events.

on_data_reader_discovery(participant, reason, info, should_be_ignored)

This method is called when a new DataReader is discovered, or a previously discovered DataReader changes its QOS or is removed.

Parameters:
  • [in] – participant Pointer to the Participant which discovered the remote reader.

  • [in] – reason The reason motivating this method to be called.

  • [in] – info Remote reader information.

  • [out] – should_be_ignored Flag to indicate the library to automatically ignore the discovered reader.

on_data_writer_discovery(participant, reason, info, should_be_ignored)

This method is called when a new DataWriter is discovered, or a previously discovered DataWriter changes its QOS or is removed.

Parameters:
  • [in] – participant Pointer to the Participant which discovered the remote writer.

  • [in] – reason The reason motivating this method to be called.

  • [in] – info Remote writer information.

  • [out] – should_be_ignored Flag to indicate the library to automatically ignore the discovered writer.

on_participant_discovery(participant, reason, info, should_be_ignored)

This method is called when a new Participant is discovered, or a previously discovered participant changes its QOS or is removed.

Parameters:
  • [out] – participant Pointer to the Participant which discovered the remote participant.

  • [out] – reason Reason of the change in the status of the discovered participant.

  • [out] – info Remote participant information. User can take ownership of the object.

  • [out] – should_be_ignored Flag to indicate the library to automatically ignore the discovered Participant.

property thisown

The membership flag

21.1.2.5. DomainParticipantQos
class fastdds.DomainParticipantQos

Class DomainParticipantQos, contains all the possible Qos that can be set for a determined participant. Please consult each of them to check for implementation details and default values.

allocation(*args)

Overload 1:

Getter for ParticipantResourceLimitsQos

Return type:

ParticipantResourceLimitsQos

Returns:

ParticipantResourceLimitsQos reference


Overload 2:

Getter for ParticipantResourceLimitsQos

Return type:

ParticipantResourceLimitsQos

Returns:

ParticipantResourceLimitsQos reference


Overload 3:

Setter for ParticipantResourceLimitsQos

Parameters:

allocation (ParticipantResourceLimitsQos) – ParticipantResourceLimitsQos

builtin_controllers_sender_thread(*args)

Overload 1:

Getter for builtin flow controllers sender threads ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 2:

Getter for builtin flow controllers sender threads ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 3:

Setter for the builtin flow controllers sender threads ThreadSettings

Parameters:

value (ThreadSettings) – New ThreadSettings to be set

compare_flow_controllers(qos)

Compares the flow controllers of two DomainParticipantQos element-wise.

Parameters:

qos (DomainParticipantQos) – The DomainParticipantQos to compare with.

Return type:

boolean

Returns:

true if the flow controllers are the same, false otherwise.

discovery_server_thread(*args)

Overload 1:

Getter for discovery server ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 2:

Getter for discovery server ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 3:

Setter for the discovery server ThreadSettings

Parameters:

value (ThreadSettings) – New ThreadSettings to be set

entity_factory(*args)

Overload 1:

Getter for EntityFactoryQosPolicy

Return type:

EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference


Overload 2:

Getter for EntityFactoryQosPolicy

Return type:

EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference


Overload 3:

Setter for EntityFactoryQosPolicy

Parameters:

value (EntityFactoryQosPolicy) – EntityFactoryQosPolicy

flow_controllers(*args)

Overload 1:

Getter for FlowControllerDescriptorList

Return type:

FlowControllerDescriptorList

Returns:

FlowControllerDescriptorList reference


Overload 2:

Getter for FlowControllerDescriptorList

Return type:

FlowControllerDescriptorList

Returns:

FlowControllerDescriptorList reference

name(*args)

Overload 1:

Getter for the Participant name

Return type:

string

Returns:

name


Overload 2:

Setter for the Participant name

Parameters:

value (string) – New name to be set.

properties(*args)

Overload 1:

Getter for PropertyPolicyQos

Return type:

PropertyPolicyQos

Returns:

PropertyPolicyQos reference


Overload 2:

Getter for PropertyPolicyQos

Return type:

PropertyPolicyQos

Returns:

PropertyPolicyQos reference


Overload 3:

Setter for PropertyPolicyQos

Parameters:

properties (PropertyPolicyQos) – PropertyPolicyQos

setup_transports(*args)

Provides a way of easily configuring transport related configuration on certain pre-defined scenarios with certain options.

Parameters:
  • transports (eprosima::fastdds::rtps::BuiltinTransports) – Defines the transport configuration scenario to setup.

  • options (eprosima::fastdds::rtps::BuiltinTransportsOptions) – Defines the options to be used in the transport configuration.

property thisown

The membership flag

timed_events_thread(*args)

Overload 1:

Getter for timed event ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 2:

Getter for timed event ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 3:

Setter for the timed event ThreadSettings

Parameters:

value (ThreadSettings) – New ThreadSettings to be set

transport(*args)

Overload 1:

Getter for TransportConfigQos

Return type:

TransportConfigQos

Returns:

TransportConfigQos reference


Overload 2:

Getter for TransportConfigQos

Return type:

TransportConfigQos

Returns:

TransportConfigQos reference


Overload 3:

Setter for TransportConfigQos

Parameters:

transport (TransportConfigQos) – TransportConfigQos

typelookup_service_thread(*args)

Overload 1:

Getter for TypeLookup service ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 2:

Getter for TypeLookup service ThreadSettings

Return type:

ThreadSettings

Returns:

rtps::ThreadSettings reference


Overload 3:

Setter for the TypeLookup service ThreadSettings

Parameters:

value (ThreadSettings) – New ThreadSettings to be set

user_data(*args)

Overload 1:

Getter for UserDataQosPolicy

Return type:

UserDataQosPolicy

Returns:

UserDataQosPolicy reference


Overload 2:

Getter for UserDataQosPolicy

Return type:

UserDataQosPolicy

Returns:

UserDataQosPolicy reference


Overload 3:

Setter for UserDataQosPolicy

Parameters:

value (UserDataQosPolicy) – UserDataQosPolicy

wire_protocol(*args)

Overload 1:

Getter for WireProtocolConfigQos

Return type:

WireProtocolConfigQos

Returns:

WireProtocolConfigQos reference


Overload 2:

Getter for WireProtocolConfigQos

Return type:

WireProtocolConfigQos

Returns:

WireProtocolConfigQos reference


Overload 3:

Setter for WireProtocolConfigQos

Parameters:

wire_protocol (WireProtocolConfigQos) – WireProtocolConfigQos

fastdds.PARTICIPANT_QOS_DEFAULT = <fastdds.DomainParticipantQos>

21.1.3. Publisher

21.1.3.1. DataWriter
class fastdds.DataWriter(*args, **kwargs)

Class DataWriter, contains the actual implementation of the behaviour of the DataWriter.

LoanInitializationKind_CONSTRUCTED_LOAN_INITIALIZATION

Use in-place constructor initialization.

This will call the constructor of the data type over the memory space being returned by ‘loan_sample’.

LoanInitializationKind_NO_LOAN_INITIALIZATION

Do not perform initialization of sample.

This is the default initialization scheme of loaned samples. It is the fastest scheme, but implies the user should take care of writing every field on the data type before calling ‘write’ on the loaned sample.

LoanInitializationKind_ZERO_LOAN_INITIALIZATION

Initialize all memory with zero-valued bytes.

The contents of the loaned sample will be zero-initialized upon return of ‘loan_sample’.

assert_liveliness()

This operation manually asserts the liveliness of the DataWriter. This is used in combination with the LivelinessQosPolicy to indicate to the Service that the entity remains active. This operation need only be used if the LIVELINESS setting is either MANUAL_BY_PARTICIPANT or MANUAL_BY_TOPIC. Otherwise, it has no effect.

Notes: Writing data via the write operation on a DataWriter asserts liveliness on the DataWriter itself and its DomainParticipant. Consequently the use of assert_liveliness is only needed if the application is not writing data regularly.

Return type:

int

Returns:

RETCODE_OK if asserted, RETCODE_ERROR otherwise

clear_history()
dispose(data, handle)

This operation requests the middleware to delete the data (the actual deletion is postponed until there is no more use for that data in the whole system). In general, applications are made aware of the deletion by means of operations on the DataReader objects that already knew that instance. This operation does not modify the value of the instance. The instance parameter is passed just for the purposes of identifying the instance. When this operation is used, the Service will automatically supply the value of the source_timestamp that is made available to DataReader objects by means of the source_timestamp attribute inside the SampleInfo. The constraints on the values of the handle parameter and the corresponding error behavior are the same specified for the unregister_instance operation.

Parameters:
  • [in] – data Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • [in] – handle InstanceHandle of the data

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if the handle introduced does not match with the one associated to the data, RETCODE_OK if the data is correctly sent and RETCODE_ERROR otherwise.

dispose_w_timestamp(instance, handle, timestamp)

This operation performs the same functions as ‘dispose’ except that the application provides the value for the ‘source_timestamp’ that is made available to DataReader objects by means of the ‘source_timestamp’ attribute inside the SampleInfo.

The constraints on the values of the handle parameter and the corresponding error behavior are the same specified for the ‘dispose’ operation.

This operation may return RETCODE_PRECONDITION_NOT_MET and RETCODE_BAD_PARAMETER under the same circumstances described for the ‘dispose’ operation.

This operation may return RETCODE_TIMEOUT and RETCODE_OUT_OF_RESOURCES under the same circumstances described for the ‘write’ operation.

Parameters:
  • instance (void) – Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • handle (InstanceHandle_t) – Instance’s key to be disposed.

  • timestamp (Time_t) – Time_t used to set the source_timestamp.

Return type:

int

Returns:

FASTDDS_EXPORTED_API

enable()

This operation enables the DataWriter

Return type:

int

Returns:

RETCODE_OK is successfully enabled. RETCODE_PRECONDITION_NOT_MET if the Publisher creating this DataWriter is not enabled.

get_instance_handle()

Returns the DataWriter’s InstanceHandle

Return type:

InstanceHandle_t

Returns:

Copy of the DataWriter InstanceHandle

get_key_value(key_holder, handle)

This operation can be used to retrieve the instance key that corresponds to an ‘instance_handle’. The operation will only fill the fields that form the key inside the key_holder instance.

This operation may return BAD_PARAMETER if the InstanceHandle_t handle does not correspond to an existing data-object known to the DataWriter. If the implementation is not able to check invalid handles then the result in this situation is unspecified.

Parameters:
  • [in,out] – key_holder Sample where the key fields will be returned.

  • [in] – handle Handle to the instance to retrieve the key values from.

Return type:

int

Returns:

Any of the standard return codes.

get_listener()

Retrieves the listener for this DataWriter.

Return type:

DataWriterListener

Returns:

Pointer to the DataWriterListener

get_liveliness_lost_status(status)

Returns the liveliness lost status

Parameters:

status (LivelinessLostStatus) – Liveliness lost status struct

Return type:

int

Returns:

RETCODE_OK

get_matched_subscription_data(subscription_data, subscription_handle)

Retrieves in a subscription associated with the DataWriter

Parameters:
  • [out] – subscription_data subscription data struct

  • subscription_handle (InstanceHandle_t) – InstanceHandle_t of the subscription

Return type:

int

Returns:

RETCODE_OK

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_matched_subscriptions(subscription_handles)

Fills the given vector with the InstanceHandle_t of matched DataReaders

Parameters:

[out] – subscription_handles Vector where the InstanceHandle_t are returned

Return type:

int

Returns:

RETCODE_OK

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_offered_deadline_missed_status(status)

Returns the offered deadline missed status

Parameters:

[out] – status Deadline missed status struct

Return type:

int

Returns:

RETCODE_OK

get_offered_incompatible_qos_status(status)

Returns the offered incompatible qos status

Parameters:

[out] – status Offered incompatible qos status struct

Return type:

int

Returns:

RETCODE_OK

get_publication_builtin_topic_data(publication_data)

Retrieve the publication data discovery information.

Parameters:

[out] – publication_data The publication data discovery information.

Return type:

int

Returns:

NOT_ENABLED if the writer has not been enabled.

Return type:

int

Returns:

OK if the publication data is returned.

get_publication_matched_status(status)

Returns the publication matched status

Parameters:

[out] – status publication matched status struct

Return type:

int

Returns:

RETCODE_OK

get_publisher()

Getter for the Publisher that creates this DataWriter

Return type:

Publisher

Returns:

Pointer to the Publisher

get_qos(*args)

Overload 1:

Retrieves the DataWriterQos for this DataWriter.

Return type:

DataWriterQos

Returns:

Reference to the current DataWriterQos


Overload 2:

Fills the DataWriterQos with the values of this DataWriter.

Parameters:

qos (DataWriterQos) – DataWriterQos object where the qos is returned.

Return type:

int

Returns:

RETCODE_OK

get_sending_locators(locators)

Get the list of locators from which this DataWriter may send data.

Parameters:

[out] – locators LocatorList where the list of locators will be stored.

Return type:

int

Returns:

NOT_ENABLED if the reader has not been enabled.

Return type:

int

Returns:

OK if a list of locators is returned.

get_topic()

Retrieves the topic for this DataWriter.

Return type:

Topic

Returns:

Pointer to the associated Topic

get_type()

Get data type associated to the DataWriter

Return type:

TypeSupport

Returns:

Copy of the TypeSupport

guid()

Returns the DataWriter’s GUID

Return type:

GUID_t

Returns:

Reference to the DataWriter GUID

loan_sample(*args)

Get a pointer to the internal pool where the user could directly write.

This method can only be used on a DataWriter for a plain data type. It will provide the user with a pointer to an internal buffer where the data type can be prepared for sending.

When using NO_LOAN_INITIALIZATION on the initialization parameter, which is the default, no assumptions should be made on the contents where the pointer points to, as it may be an old pointer being reused. See ‘LoanInitializationKind’ for more details.

Once the sample has been prepared, it can then be published by calling ‘write’. After a successful call to ‘write’, the middleware takes ownership of the loaned pointer again, and the user should not access that memory again.

If, for whatever reason, the sample is not published, the loan can be returned by calling ‘discard_loan’.

Parameters:
  • [out] – sample Pointer to the sample on the internal pool.

  • [in] – initialization How to initialize the loaned sample.

Return type:

int

Returns:

RETCODE_ILLEGAL_OPERATION when the data type does not support loans.

Return type:

int

Returns:

RETCODE_NOT_ENABLED if the writer has not been enabled.

Return type:

int

Returns:

RETCODE_OUT_OF_RESOURCES if the pool has been exhausted.

Return type:

int

Returns:

RETCODE_OK if a pointer to a sample is successfully obtained.

lookup_instance(instance)

NOT YET IMPLEMENTED

Takes as a parameter an instance and returns a handle that can be used in subsequent operations that accept an instance handle as an argument. The instance parameter is only used for the purpose of examining the fields that define the key.

Parameters:

[in] – instance Data pointer to the sample

Return type:

InstanceHandle_t

Returns:

handle of the given instance

register_instance(instance)

Informs that the application will be modifying a particular instance. It gives an opportunity to the middleware to pre-configure itself to improve performance.

Parameters:

[in] – instance Sample used to get the instance’s key.

Return type:

InstanceHandle_t

Returns:

Handle containing the instance’s key. This handle could be used in successive write or dispose operations. In case of error, HANDLE_NIL will be returned.

register_instance_w_timestamp(instance, timestamp)

This operation performs the same function as register_instance and can be used instead of ‘register_instance’ in the cases where the application desires to specify the value for the ‘source_timestamp’. The ‘source_timestamp’ potentially affects the relative order in which readers observe events from multiple writers. See the QoS policy ‘DESTINATION_ORDER’.

This operation may block and return RETCODE_TIMEOUT under the same circumstances described for the ‘write’ operation.

This operation may return RETCODE_OUT_OF_RESOURCES under the same circumstances described for the ‘write’ operation.

Parameters:
  • instance (void) – Sample used to get the instance’s key.

  • timestamp (Time_t) – Time_t used to set the source_timestamp.

Return type:

InstanceHandle_t

Returns:

Handle containing the instance’s key.

set_listener(*args)
set_qos(qos)

Establishes the DataWriterQos for this DataWriter.

Parameters:

qos (DataWriterQos) – DataWriterQos to be set

Return type:

int

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

property thisown

The membership flag

unregister_instance(instance, handle)

This operation reverses the action of register_instance. It should only be called on an instance that is currently registered. Informs the middleware that the DataWriter is not intending to modify any more of that data instance. Also indicates that the middleware can locally remove all information regarding that instance.

Parameters:
  • [in] – instance Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • [in] – handle Instance’s key to be unregistered.

Return type:

int

Returns:

Returns the operation’s result. If the operation finishes successfully, RETCODE_OK is returned.

unregister_instance_w_timestamp(instance, handle, timestamp)

This operation performs the same function as ‘unregister_instance’ and can be used instead of ‘unregister_instance’ in the cases where the application desires to specify the value for the ‘source_timestamp’. The ‘source_timestamp’ potentially affects the relative order in which readers observe events from multiple writers. See the QoS policy ‘DESTINATION_ORDER’.

The constraints on the values of the handle parameter and the corresponding error behavior are the same specified for the ‘unregister_instance’ operation.

This operation may block and return RETCODE_TIMEOUT under the same circumstances described for the write operation

Parameters:
  • instance (void) – Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • handle (InstanceHandle_t) – Instance’s key to be unregistered.

  • timestamp (Time_t) – Time_t used to set the source_timestamp.

Return type:

int

Returns:

Handle containing the instance’s key.

wait_for_acknowledgments(*args)

Overload 1:

Waits the current thread until all writers have received their acknowledgments.

Parameters:

max_wait (Duration_t) – Maximum blocking time for this operation

Return type:

int

Returns:

RETCODE_OK if the DataWriter receive the acknowledgments before the time expires and RETCODE_ERROR otherwise


Overload 2:

Block the current thread until the writer has received the acknowledgment corresponding to the given instance. Operations performed on the same instance while the current thread is waiting will not be taken into consideration, i.e. this method may return RETCODE_OK with those operations unacknowledged.

Parameters:
  • instance (void) – Sample used to deduce instance’s key in case of handle parameter is HANDLE_NIL.

  • handle (InstanceHandle_t) – Instance handle of the data.

  • max_wait (Duration_t) – Maximum blocking time for this operation.

Return type:

int

Returns:

RETCODE_NOT_ENABLED if the writer has not been enabled.

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if instance is not a valid pointer.

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if the topic does not have a key, the key is unknown to the writer, or the key is not consistent with handle.

Return type:

int

Returns:

RETCODE_OK if the DataWriter received the acknowledgments before the time expired.

Return type:

int

Returns:

RETCODE_TIMEOUT otherwise.

write(*args)

Overload 1:

Write data to the topic.

Parameters:

data (void) – Pointer to the data

Return type:

int

Returns:

RETCODE_OK if the data is correctly sent or a ReturnCode related to the specific error otherwise.


Overload 2:

Write data with params to the topic.

Parameters:
  • data (void) – Pointer to the data

  • params (WriteParams) – Extra write parameters.

Return type:

int

Returns:

RETCODE_OK if the data is correctly sent or a ReturnCode related to the specific error otherwise.


Overload 3:

Write data with handle.

The special value HANDLE_NIL can be used for the parameter handle.This indicates that the identity of the instance should be automatically deduced from the instance_data (by means of the key).

Parameters:
  • data (void) – Pointer to the data

  • handle (InstanceHandle_t) – InstanceHandle_t.

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if the handle introduced does not match with the one associated to the data, RETCODE_OK if the data is correctly sent and RETCODE_ERROR otherwise.

write_w_timestamp(data, handle, timestamp)

This operation performs the same function as write except that it also provides the value for the ‘source_timestamp’ that is made available to DataReader objects by means of the ‘eprosima::fastdds::dds::SampleInfo::source_timestamp’ attribute “source_timestamp” inside the SampleInfo. The constraints on the values of the handle parameter and the corresponding error behavior are the same specified for the ‘write’ operation. This operation may block and return RETCODE_TIMEOUT under the same circumstances described for the ‘write’ operation. This operation may return RETCODE_OUT_OF_RESOURCES, RETCODE_PRECONDITION_NOT_MET or RETCODE_BAD_PARAMETER under the same circumstances described for the write operation.

Parameters:
  • data (void) – Pointer to the data

  • handle (InstanceHandle_t) – InstanceHandle_t

  • timestamp (Time_t) – Time_t used to set the source_timestamp.

Return type:

int

Returns:

Any of the standard return codes.

21.1.3.2. DataWriterListener
class fastdds.DataWriterListener

Class DataWriterListener, allows the end user to implement callbacks triggered by certain events.

on_liveliness_lost(writer, status)

Method called when the liveliness of a DataWriter is lost

Parameters:
  • writer (DataWriter) – Pointer to the associated DataWriter

  • status (LivelinessLostStatus) – The liveliness lost status

on_offered_deadline_missed(writer, status)

A method called when a deadline is missed

Parameters:
  • writer (DataWriter) – Pointer to the associated DataWriter

  • status (OfferedDeadlineMissedStatus) – The deadline missed status

on_offered_incompatible_qos(writer, status)

A method called when an incompatible QoS is offered

Parameters:
  • writer (DataWriter) – Pointer to the associated DataWriter

  • status (OfferedIncompatibleQosStatus) – The deadline missed status

on_publication_matched(writer, info)

This method is called when the DataWriter is matched (or unmatched) against an endpoint.

Parameters:
on_unacknowledged_sample_removed(writer, instance)

Method called when a sample has been removed unacknowledged

Parameters:
  • writer (DataWriter) – Pointer to the associated DataWriter

  • instance (InstanceHandle_t) – Handle to the instance the sample was removed from

property thisown

The membership flag

21.1.3.3. DataWriterQos
class fastdds.DataWriterQos

Class DataWriterQos, containing all the possible Qos that can be set for a determined DataWriter. Although these values can be and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

data_sharing(*args)

Overload 1:

Getter for DataSharingQosPolicy

Return type:

DataSharingQosPolicy

Returns:

DataSharingQosPolicy reference


Overload 2:

Getter for DataSharingQosPolicy

Return type:

DataSharingQosPolicy

Returns:

DataSharingQosPolicy reference


Overload 3:

Setter for DataSharingQosPolicy

Parameters:

data_sharing (DataSharingQosPolicy) – new value for the DataSharingQosPolicy

deadline(*args)

Overload 1:

Getter for DeadlineQosPolicy

Return type:

DeadlineQosPolicy

Returns:

DeadlineQosPolicy reference


Overload 2:

Getter for DeadlineQosPolicy

Return type:

DeadlineQosPolicy

Returns:

DeadlineQosPolicy reference


Overload 3:

Setter for DeadlineQosPolicy

Parameters:

deadline (DeadlineQosPolicy) – new value for the DeadlineQosPolicy

destination_order(*args)

Overload 1:

Getter for DestinationOrderQosPolicy

Return type:

DestinationOrderQosPolicy

Returns:

DestinationOrderQosPolicy reference


Overload 2:

Getter for DestinationOrderQosPolicy

Return type:

DestinationOrderQosPolicy

Returns:

DestinationOrderQosPolicy reference


Overload 3:

Setter for DestinationOrderQosPolicy

Parameters:

destination_order (DestinationOrderQosPolicy) – new value for the DestinationOrderQosPolicy

durability(*args)

Overload 1:

Getter for DurabilityQosPolicy

Return type:

DurabilityQosPolicy

Returns:

DurabilityQosPolicy reference


Overload 2:

Getter for DurabilityQosPolicy

Return type:

DurabilityQosPolicy

Returns:

DurabilityQosPolicy reference


Overload 3:

Setter for DurabilityQosPolicy

Parameters:

durability (DurabilityQosPolicy) – new value for the DurabilityQosPolicy

durability_service(*args)

Overload 1:

Getter for DurabilityServiceQosPolicy

Return type:

DurabilityServiceQosPolicy

Returns:

DurabilityServiceQosPolicy reference


Overload 2:

Getter for DurabilityServiceQosPolicy

Return type:

DurabilityServiceQosPolicy

Returns:

DurabilityServiceQosPolicy reference


Overload 3:

Setter for DurabilityServiceQosPolicy

Parameters:

durability_service (DurabilityServiceQosPolicy) – new value for the DurabilityServiceQosPolicy

endpoint(*args)

Overload 1:

Getter for RTPSEndpointQos

Return type:

RTPSEndpointQos

Returns:

RTPSEndpointQos reference


Overload 2:

Getter for RTPSEndpointQos :rtype: RTPSEndpointQos :return: RTPSEndpointQos reference


Overload 3:

Setter for RTPSEndpointQos

Parameters:

endpoint (RTPSEndpointQos) – new value for the RTPSEndpointQos

get_writerqos(pqos, tqos)
history(*args)

Overload 1:

Getter for HistoryQosPolicy

Return type:

HistoryQosPolicy

Returns:

HistoryQosPolicy reference


Overload 2:

Getter for HistoryQosPolicy

Return type:

HistoryQosPolicy

Returns:

HistoryQosPolicy reference


Overload 3:

Setter for HistoryQosPolicy

Parameters:

history (HistoryQosPolicy) – new value for the HistoryQosPolicy

latency_budget(*args)

Overload 1:

Getter for LatencyBudgetQosPolicy

Return type:

LatencyBudgetQosPolicy

Returns:

LatencyBudgetQosPolicy reference


Overload 2:

Getter for LatencyBudgetQosPolicy

Return type:

LatencyBudgetQosPolicy

Returns:

LatencyBudgetQosPolicy reference


Overload 3:

Setter for LatencyBudgetQosPolicy

Parameters:

latency_budget (LatencyBudgetQosPolicy) – new value for the LatencyBudgetQosPolicy

lifespan(*args)

Overload 1:

Getter for LifespanQosPolicy

Return type:

LifespanQosPolicy

Returns:

LifespanQosPolicy reference


Overload 2:

Getter for LifespanQosPolicy

Return type:

LifespanQosPolicy

Returns:

LifespanQosPolicy reference


Overload 3:

Setter for LifespanQosPolicy

Parameters:

lifespan (LifespanQosPolicy) – new value for the LifespanQosPolicy

liveliness(*args)

Overload 1:

Getter for LivelinessQosPolicy

Return type:

LivelinessQosPolicy

Returns:

LivelinessQosPolicy reference


Overload 2:

Getter for LivelinessQosPolicy

Return type:

LivelinessQosPolicy

Returns:

LivelinessQosPolicy reference


Overload 3:

Setter for LivelinessQosPolicy

Parameters:

liveliness (LivelinessQosPolicy) – new value for the LivelinessQosPolicy

ownership(*args)

Overload 1:

Getter for OwnershipQosPolicy

Return type:

OwnershipQosPolicy

Returns:

OwnershipQosPolicy reference


Overload 2:

Getter for OwnershipQosPolicy

Return type:

OwnershipQosPolicy

Returns:

OwnershipQosPolicy reference


Overload 3:

Setter for OwnershipQosPolicy

Parameters:

ownership (OwnershipQosPolicy) – new value for the OwnershipQosPolicy

ownership_strength(*args)

Overload 1:

Getter for OwnershipStrengthQosPolicy

Return type:

OwnershipStrengthQosPolicy

Returns:

OwnershipStrengthQosPolicy reference


Overload 2:

Getter for OwnershipStrengthQosPolicy

Return type:

OwnershipStrengthQosPolicy

Returns:

OwnershipStrengthQosPolicy reference


Overload 3:

Setter for OwnershipStrengthQosPolicy

Parameters:

ownership_strength (OwnershipStrengthQosPolicy) – new value for the OwnershipStrengthQosPolicy

properties(*args)

Overload 1:

Getter for PropertyPolicyQos

Return type:

PropertyPolicyQos

Returns:

PropertyPolicyQos reference


Overload 2:

Getter for PropertyPolicyQos

Return type:

PropertyPolicyQos

Returns:

PropertyPolicyQos reference


Overload 3:

Setter for PropertyPolicyQos

Parameters:

properties (PropertyPolicyQos) – new value for the PropertyPolicyQos

publish_mode(*args)

Overload 1:

Getter for PublishModeQosPolicy

Return type:

PublishModeQosPolicy

Returns:

PublishModeQosPolicy reference


Overload 2:

Getter for PublishModeQosPolicy

Return type:

PublishModeQosPolicy

Returns:

PublishModeQosPolicy reference


Overload 3:

Setter for PublishModeQosPolicy

Parameters:

publish_mode (PublishModeQosPolicy) – new value for the PublishModeQosPolicy

reliability(*args)

Overload 1:

Getter for ReliabilityQosPolicy

Return type:

ReliabilityQosPolicy

Returns:

ReliabilityQosPolicy reference


Overload 2:

Getter for ReliabilityQosPolicy

Return type:

ReliabilityQosPolicy

Returns:

ReliabilityQosPolicy reference


Overload 3:

Setter for ReliabilityQosPolicy

Parameters:

reliability (ReliabilityQosPolicy) – new value for the ReliabilityQosPolicy

reliable_writer_qos(*args)

Overload 1:

Getter for RTPSReliableWriterQos

Return type:

RTPSReliableWriterQos

Returns:

RTPSReliableWriterQos reference


Overload 2:

Getter for RTPSReliableWriterQos

Return type:

RTPSReliableWriterQos

Returns:

RTPSReliableWriterQos reference


Overload 3:

Setter for RTPSReliableWriterQos

Parameters:

reliable_writer_qos (RTPSReliableWriterQos) – new value for the RTPSReliableWriterQos

resource_limits(*args)

Overload 1:

Getter for ResourceLimitsQosPolicy

Return type:

ResourceLimitsQosPolicy

Returns:

ResourceLimitsQosPolicy reference


Overload 2:

Getter for ResourceLimitsQosPolicy

Return type:

ResourceLimitsQosPolicy

Returns:

ResourceLimitsQosPolicy reference


Overload 3:

Setter for ResourceLimitsQosPolicy

Parameters:

resource_limits (ResourceLimitsQosPolicy) – new value for the ResourceLimitsQosPolicy

property thisown

The membership flag

transport_priority(*args)

Overload 1:

Getter for TransportPriorityQosPolicy

Return type:

TransportPriorityQosPolicy

Returns:

TransportPriorityQosPolicy reference


Overload 2:

Getter for TransportPriorityQosPolicy

Return type:

TransportPriorityQosPolicy

Returns:

TransportPriorityQosPolicy reference


Overload 3:

Setter for TransportPriorityQosPolicy

Parameters:

transport_priority (TransportPriorityQosPolicy) – new value for the TransportPriorityQosPolicy

user_data(*args)

Overload 1:

Getter for UserDataQosPolicy

Return type:

UserDataQosPolicy

Returns:

UserDataQosPolicy reference


Overload 2:

Getter for UserDataQosPolicy

Return type:

UserDataQosPolicy

Returns:

UserDataQosPolicy reference


Overload 3:

Setter for UserDataQosPolicy

Parameters:

user_data (UserDataQosPolicy) – new value for the UserDataQosPolicy

writer_data_lifecycle(*args)

Overload 1:

Getter for WriterDataLifecycleQosPolicy

Return type:

WriterDataLifecycleQosPolicy

Returns:

WriterDataLifecycleQosPolicy reference


Overload 2:

Getter for WriterDataLifecycleQosPolicy

Return type:

WriterDataLifecycleQosPolicy

Returns:

WriterDataLifecycleQosPolicy reference


Overload 3:

Setter for WriterDataLifecycleQosPolicy

Parameters:

writer_data_lifecycle (WriterDataLifecycleQosPolicy) – new value for the WriterDataLifecycleQosPolicy

writer_resource_limits(*args)

Overload 1:

Getter for WriterResourceLimitsQos

Return type:

WriterResourceLimitsQos

Returns:

WriterResourceLimitsQos reference


Overload 2:

Getter for WriterResourceLimitsQos

Return type:

WriterResourceLimitsQos

Returns:

WriterResourceLimitsQos reference


Overload 3:

Setter for WriterResourceLimitsQos

Parameters:

writer_resource_limits (WriterResourceLimitsQos) – new value for the WriterResourceLimitsQos

fastdds.DATAWRITER_QOS_DEFAULT = <fastdds.DataWriterQos>
fastdds.DATAWRITER_QOS_USE_TOPIC_QOS = <fastdds.DataWriterQos>
21.1.3.4. Publisher
class fastdds.Publisher(*args, **kwargs)

Class Publisher, used to send data to associated subscribers.

begin_coherent_changes()

Signals the beginning of a set of coherent cache changes using the Datawriters attached to the publisher

Return type:

int

Returns:

RETCODE_OK if successful, an error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

static copy_from_topic_qos(writer_qos, topic_qos)

Copies TopicQos into the corresponding DataWriterQos

Parameters:
  • [out] – writer_qos

  • [in] – topic_qos

Return type:

int

Returns:

RETCODE_OK if successful, an error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

create_datawriter(*args)

This operation creates a DataWriter. The returned DataWriter will be attached and belongs to the Publisher.

Parameters:
  • topic (Topic) – Topic the DataWriter will be listening

  • qos – QoS of the DataWriter.

  • listener (DataWriterListener) – Pointer to the listener (default: nullptr).

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all).

Return type:

DataWriter

Returns:

Pointer to the created DataWriter. nullptr if failed.

create_datawriter_with_profile(*args)

This operation creates a DataWriter. The returned DataWriter will be attached and belongs to the Publisher.

Parameters:
  • topic (Topic) – Topic the DataWriter will be listening

  • profile_name (string) – DataWriter profile name.

  • listener (DataWriterListener) – Pointer to the listener (default: nullptr).

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all).

Return type:

DataWriter

Returns:

Pointer to the created DataWriter. nullptr if failed.

delete_contained_entities()

Deletes all contained DataWriters

Return type:

int

Returns:

RETCODE_OK if successful, an error code otherwise

delete_datawriter(writer)

This operation deletes a DataWriter that belongs to the Publisher.

The delete_datawriter operation must be called on the same Publisher object used to create the DataWriter. If delete_datawriter is called on a different Publisher, the operation will have no effect and it will return false.

The deletion of the DataWriter will automatically unregister all instances. Depending on the settings of the WRITER_DATA_LIFECYCLE QosPolicy, the deletion of the DataWriter may also dispose all instances.

Parameters:

writer (DataWriter) – DataWriter to delete

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if it does not belong to this Publisher, RETCODE_OK if it is correctly deleted and RETCODE_ERROR otherwise.

enable()

This operation enables the Publisher

Return type:

int

Returns:

RETCODE_OK is successfully enabled. RETCODE_PRECONDITION_NOT_MET if the participant creating this Publisher is not enabled.

end_coherent_changes()

Signals the end of a set of coherent cache changes

Return type:

int

Returns:

RETCODE_OK if successful, an error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_datawriter_qos_from_profile(*args)

Overload 1:

Fills the ‘DataWriterQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – DataWriter profile name.

  • qos (DataWriterQos) – ‘DataWriterQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘DataWriterQos’ with the values of the XML profile, and also its corresponding topic name (if specified).

Parameters:
  • profile_name (string) – DataWriter profile name.

  • qos (DataWriterQos) – ‘DataWriterQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_datawriter_qos_from_xml(*args)

Overload 1:

Fills the ‘DataWriterQos’ with the first DataWriter profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataWriterQos) – ‘DataWriterQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘DataWriterQos’ with the first DataWriter profile found in the provided XML, and also its corresponding topic name (if specified).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataWriterQos) – ‘DataWriterQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 3:

Fills the ‘DataWriterQos’ with the DataWriter profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataWriterQos) – ‘DataWriterQos’ object where the qos is returned.

  • profile_name (string) – DataWriter profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 4:

Fills the ‘DataWriterQos’ with the DataWriter profile with profile_name to be found in the provided XML, and also its corresponding topic name (if specified).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataWriterQos) – ‘DataWriterQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

  • profile_name (string) – DataWriter profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_datawriters(writers)

Fills the given vector with all the datawriters of this publisher.

Parameters:

writers (DataWriterVector) – Vector where the DataWriters are returned

Return type:

boolean

Returns:

true

get_default_datawriter_qos(*args)

Overload 1:

This operation returns the default value of the DataWriter QoS, that is, the QoS policies which will be used for newly created DataWriter entities in the case where the QoS policies are defaulted in the create_datawriter operation.

The values retrieved by get_default_datawriter_qos will match the set of values specified on the last successful call to set_default_datawriter_qos, or else, if the call was never made, the default values.

Return type:

DataWriterQos

Returns:

Current default WriterQos


Overload 2:

This operation retrieves the default value of the DataWriter QoS, that is, the QoS policies which will be used for newly created DataWriter entities in the case where the QoS policies are defaulted in the create_datawriter operation.

The values retrieved by get_default_datawriter_qos will match the set of values specified on the last successful call to set_default_datawriter_qos, or else, if the call was never made, the default values.

Parameters:

qos (DataWriterQos) – Reference to the current default WriterQos.

Return type:

int

Returns:

RETCODE_OK

get_default_datawriter_qos_from_xml(*args)

Overload 1:

Fills the ‘DataWriterQos’ with the default DataWriter profile found in the provided XML (if there is).

Notes: This method does not update the default datawriter qos (returned by get_default_datawriter_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataWriterQos) – ‘DataWriterQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘DataWriterQos’ with the default DataWriter profile found in the provided XML (if there is), and also its corresponding topic name (if specified).

Notes: This method does not update the default datawriter qos (returned by get_default_datawriter_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataWriterQos) – ‘DataWriterQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_instance_handle()

Returns the Publisher’s handle.

Return type:

InstanceHandle_t

Returns:

InstanceHandle of this Publisher.

get_listener()

Retrieves the attached PublisherListener.

Return type:

PublisherListener

Returns:

PublisherListener pointer

get_participant()

This operation returns the DomainParticipant to which the Publisher belongs.

Return type:

DomainParticipant

Returns:

Pointer to the DomainParticipant

get_qos(*args)

Overload 1:

Allows accessing the Publisher Qos.

Return type:

PublisherQos

Returns:

PublisherQos reference


Overload 2:

Retrieves the Publisher Qos.

Return type:

int

Returns:

RETCODE_OK

has_datawriters()

This operation checks if the publisher has DataWriters

Return type:

boolean

Returns:

true if the publisher has one or several DataWriters, false otherwise

lookup_datawriter(topic_name)

This operation retrieves a previously created DataWriter belonging to the Publisher that is attached to a Topic with a matching topic_name. If no such DataWriter exists, the operation will return nullptr.

If multiple DataWriter attached to the Publisher satisfy this condition, then the operation will return one of them. It is not specified which one.

Parameters:

topic_name (string) – Name of the Topic

Return type:

DataWriter

Returns:

Pointer to a previously created DataWriter associated to a Topic with the requested topic_name

resume_publications()

Indicates to FastDDS that the modifications to the DataWriters are complete.

Return type:

int

Returns:

RETCODE_OK if successful, an error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

set_default_datawriter_qos(qos)

This operation sets a default value of the DataWriter QoS policies which will be used for newly created DataWriter entities in the case where the QoS policies are defaulted in the create_datawriter operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return false.

The special value DATAWRITER_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_datawriter_qos operation had never been called.

Parameters:

qos (DataWriterQos) – DataWriterQos to be set

Return type:

int

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

set_listener(*args)

Overload 1:

Modifies the PublisherListener, sets the mask to StatusMask::all()

Parameters:

listener (PublisherListener) – new value for the PublisherListener

Return type:

int

Returns:

RETCODE_OK


Overload 2:

Modifies the PublisherListener.

Parameters:
  • listener (PublisherListener) – new value for the PublisherListener

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to

Return type:

int

Returns:

RETCODE_OK

set_qos(qos)

Allows modifying the Publisher Qos. The given Qos must be supported by the PublisherQos.

Parameters:

qos (PublisherQos) – PublisherQos to be set

Return type:

int

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

suspend_publications()

Indicates to FastDDS that the contained DataWriters are about to be modified

Return type:

int

Returns:

RETCODE_OK if successful, an error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

property thisown

The membership flag

wait_for_acknowledgments(max_wait)

This operation blocks the calling thread until either all data written by the reliable DataWriter entities is acknowledged by all matched reliable DataReader entities, or else the duration specified by the max_wait parameter elapses, whichever happens first. A return value of true indicates that all the samples written have been acknowledged by all reliable matched data readers; a return value of false indicates that max_wait elapsed before all the data was acknowledged.

Parameters:

max_wait (Duration_t) – Maximum blocking time for this operation

Return type:

int

Returns:

RETCODE_TIMEOUT if the function takes more than the maximum blocking time established, RETCODE_OK if the Publisher receives the acknowledgments and RETCODE_ERROR otherwise.

21.1.3.5. PublisherListener
class fastdds.PublisherListener

Class PublisherListener, allows the end user to implement callbacks triggered by certain events. It inherits all the DataWriterListener callbacks.

property thisown

The membership flag

21.1.3.6. PublisherQos
class fastdds.PublisherQos

Class PublisherQos, containing all the possible Qos that can be set for a determined Publisher. Although these values can be set and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

entity_factory(*args)

Overload 1:

Getter for EntityFactoryQosPolicy

Return type:

EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference


Overload 2:

Getter for EntityFactoryQosPolicy

Return type:

EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference


Overload 3:

Setter for EntityFactoryQosPolicy

Parameters:

entity_factory (EntityFactoryQosPolicy) – EntityFactoryQosPolicy

group_data(*args)

Overload 1:

Getter for GroupDataQosPolicy

Return type:

GroupDataQosPolicy

Returns:

GroupDataQosPolicy reference


Overload 2:

Getter for GroupDataQosPolicy

Return type:

GroupDataQosPolicy

Returns:

GroupDataQosPolicy reference


Overload 3:

Setter for GroupDataQosPolicy

Parameters:

group_data (GroupDataQosPolicy) – GroupDataQosPolicy

partition(*args)

Overload 1:

Getter for PartitionQosPolicy

Return type:

PartitionQosPolicy

Returns:

PartitionQosPolicy reference


Overload 2:

Getter for PartitionQosPolicy

Return type:

PartitionQosPolicy

Returns:

PartitionQosPolicy reference


Overload 3:

Setter for PartitionQosPolicy

Parameters:

partition (PartitionQosPolicy) – PartitionQosPolicy

presentation(*args)

Overload 1:

Getter for PresentationQosPolicy

Return type:

PresentationQosPolicy

Returns:

PresentationQosPolicy reference


Overload 2:

Getter for PresentationQosPolicy

Return type:

PresentationQosPolicy

Returns:

PresentationQosPolicy reference


Overload 3:

Setter for PresentationQosPolicy

Parameters:

presentation (PresentationQosPolicy) – PresentationQosPolicy

property thisown

The membership flag

fastdds.PUBLISHER_QOS_DEFAULT = <fastdds.PublisherQos>
21.1.3.7. RTPSReliableWriterQos
class fastdds.RTPSReliableWriterQos

Qos Policy to configure the DisablePositiveACKsQos and the writer timing attributes

clear()
property disable_heartbeat_piggyback

Disable heartbeat piggyback mechanism.

property disable_positive_acks

Disable positive acks QoS, implemented in the library.

property thisown

The membership flag

property times

Writer Timing Attributes

21.1.4. Subscriber

21.1.4.1. DataReader
class fastdds.DataReader(*args, **kwargs)

Class DataReader, contains the actual implementation of the behaviour of the Subscriber.

create_querycondition(sample_states, view_states, instance_states, query_expression, query_parameters)

This operation creates a QueryCondition. The returned QueryCondition will be attached and belong to the DataReader.

Parameters:
  • [in] – sample_states Only data samples with sample_state matching one of these will trigger the created condition.

  • [in] – view_states Only data samples with view_state matching one of these will trigger the created condition.

  • [in] – instance_states Only data samples with instance_state matching one of these will trigger the created condition.

  • [in] – query_expression Only data samples matching this query will trigger the created condition.

  • [in] – query_parameters Value of the parameters on the query expression.

Return type:

eprosima::fastdds::dds::QueryCondition

Returns:

pointer to the created QueryCondition, nullptr in case of error.

create_readcondition(sample_states, view_states, instance_states)

This operation creates a ReadCondition. The returned ReadCondition will be attached and belong to the DataReader.

Parameters:
  • [in] – sample_states Only data samples with sample_state matching one of these will trigger the created condition.

  • [in] – view_states Only data samples with view_state matching one of these will trigger the created condition.

  • [in] – instance_states Only data samples with instance_state matching one of these will trigger the created condition.

Return type:

ReadCondition

Returns:

pointer to the created ReadCondition, nullptr in case of error.

delete_contained_entities()

This operation deletes all the entities that were created by means of the “create” operations on the DataReader. That is, it deletes all contained ReadCondition and QueryCondition objects.

The operation will return PRECONDITION_NOT_MET if the any of the contained entities is in a state where it cannot be deleted.

Return type:

int

Returns:

Any of the standard return codes.

delete_readcondition(a_condition)

This operation deletes a ReadCondition attached to the DataReader.

Parameters:

a_condition (ReadCondition) – pointer to a ReadCondition belonging to the DataReader

Return type:

int

Returns:

RETCODE_OK

enable()

This operation enables the DataReader.

Return type:

int

Returns:

RETCODE_OK is successfully enabled. RETCODE_PRECONDITION_NOT_MET if the Subscriber creating this DataReader is not enabled.

get_first_untaken_info(info)

Returns information about the first untaken sample. This method is meant to be called prior to a read() or take() operation as it does not modify the status condition of the entity.

Parameters:

[out] – info Pointer to a SampleInfo_t structure to store first untaken sample information.

Return type:

int

Returns:

RETCODE_OK if sample info was returned. RETCODE_NO_DATA if there is no sample to take.

get_instance_handle()

Getter for the associated InstanceHandle.

Return type:

InstanceHandle_t

Returns:

Copy of the InstanceHandle

get_key_value(key_holder, handle)

NOT YET IMPLEMENTED

This operation can be used to retrieve the instance key that corresponds to an instance_handle. The operation will only fill the fields that form the key inside the key_holder instance.

This operation may return BAD_PARAMETER if the InstanceHandle_t a_handle does not correspond to an existing data-object known to the DataReader. If the implementation is not able to check invalid handles then the result in this situation is unspecified.

Parameters:
  • [in,out] – key_holder

  • [in] – handle

Return type:

int

Returns:

Any of the standard return codes.

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_listener()

Getter for the DataReaderListener

Return type:

DataReaderListener

Returns:

Pointer to the DataReaderListener

get_listening_locators(locators)

Get the list of locators on which this DataReader is listening.

Parameters:

[out] – locators LocatorList where the list of locators will be stored.

Return type:

int

Returns:

NOT_ENABLED if the reader has not been enabled.

Return type:

int

Returns:

OK if a list of locators is returned.

get_liveliness_changed_status(status)

Get the liveliness changed status.

Parameters:

[out] – status LivelinessChangedStatus object where the status is returned.

Return type:

int

Returns:

RETCODE_OK

get_matched_publication_data(publication_data, publication_handle)

Retrieves in a publication associated with the DataWriter

Parameters:
  • [out] – publication_data publication data struct

  • publication_handle (InstanceHandle_t) – InstanceHandle_t of the publication

Return type:

int

Returns:

RETCODE_OK

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_matched_publications(publication_handles)

Fills the given vector with the InstanceHandle_t of matched DataReaders

Parameters:

[out] – publication_handles Vector where the InstanceHandle_t are returned

Return type:

int

Returns:

RETCODE_OK

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_qos(*args)

Overload 1:

Getter for the DataReaderQos.

Return type:

DataReaderQos

Returns:

Pointer to the DataReaderQos.


Overload 2:

Getter for the DataReaderQos.

Parameters:

[in] – qos DataReaderQos where the qos is returned.

Return type:

int

Returns:

RETCODE_OK

get_requested_deadline_missed_status(status)

Get the requested deadline missed status.

Return type:

int

Returns:

The deadline missed status.

get_requested_incompatible_qos_status(status)

Get the requested incompatible qos status.

Parameters:

[out] – status Requested incompatible qos status.

Return type:

int

Returns:

RETCODE_OK

get_sample_lost_status(status)

Get the SAMPLE_LOST communication status

Parameters:

[out] – status SampleLostStatus object where the status is returned.

Return type:

int

Returns:

RETCODE_OK

get_sample_rejected_status(status)

Get the SAMPLE_REJECTED communication status

Parameters:

[out] – status SampleRejectedStatus object where the status is returned.

Return type:

int

Returns:

RETCODE_OK

get_subscriber()

Getter for the Subscriber :rtype: Subscriber :return: Subscriber pointer

get_subscription_builtin_topic_data(subscription_data)

Retrieve the subscription data discovery information.

Parameters:

[out] – subscription_data The subscription data discovery information.

Return type:

int

Returns:

NOT_ENABLED if the reader has not been enabled.

Return type:

int

Returns:

OK if the subscription data is returned.

get_subscription_matched_status(status)

Returns the subscription matched status

Parameters:

[out] – status subscription matched status struct

Return type:

int

Returns:

RETCODE_OK

get_topicdescription()

Get TopicDescription.

Return type:

TopicDescription

Returns:

TopicDescription pointer.

get_unread_count(*args)

Overload 1:

Get the number of samples pending to be read. The number includes samples that may not yet be available to be read or taken by the user, due to samples being received out of order.

Return type:

int

Returns:

the number of samples on the reader history that have never been read.


Overload 2:

Get the number of samples pending to be read.

Parameters:

mark_as_read (boolean) – Whether the unread samples should be marked as read or not.

Return type:

int

Returns:

the number of samples on the reader history that have never been read.

guid(*args)

Overload 1:

Get associated GUID.

Return type:

GUID_t

Returns:

Associated GUID


Overload 2:

Get associated GUID.

Return type:

GUID_t

Returns:

Associated GUID

is_sample_valid(data, info)

Checks whether a loaned sample is still valid or is corrupted. Calling this method on a sample which has not been loaned, or one for which the loan has been returned yields undefined behavior.

Parameters:
  • data (void) – Pointer to the sample data to check

  • info (SampleInfo) – Pointer to the SampleInfo related to data

Return type:

boolean

Returns:

true if the sample is valid

lookup_instance(instance)

Takes as a parameter an instance and returns a handle that can be used in subsequent operations that accept an instance handle as an argument. The instance parameter is only used for the purpose of examining the fields that define the key.

Parameters:

[in] – instance Data pointer to the sample

Return type:

InstanceHandle_t

Returns:

handle of the given instance.

Return type:

InstanceHandle_t

Returns:

HANDLE_NIL if instance is nullptr.

Return type:

InstanceHandle_t

Returns:

HANDLE_NIL if there is no instance on the DataReader’s history with the same key as instance.

read(*args)

Access a collection of data samples from the DataReader.

This operation accesses a collection of Data values from the DataReader. The caller can limit the size of the returned collection with the max_samples parameter.

The properties of the data_values collection and the setting of the ‘PresentationQosPolicy’ may impose further limits on the size of the returned ‘list.’

  1. If ‘PresentationQosPolicy::access_scope’ is ‘INSTANCE_PRESENTATION_QOS’, then the returned collection is a ‘list’ where samples belonging to the same data-instance are consecutive.

  2. If ‘PresentationQosPolicy::access_scope’ is ‘TOPIC_PRESENTATION_QOS’ and ‘PresentationQosPolicy::ordered_access’ is set to false, then the returned collection is a ‘list’ where samples belonging to the same data-instance are consecutive.

  3. If ‘PresentationQosPolicy::access_scope’ is ‘TOPIC_PRESENTATION_QOS’ and ‘PresentationQosPolicy::ordered_access’ is set to true, then the returned collection is a ‘list’ where samples belonging to the same instance may or may not be consecutive. This is because to preserve order it may be necessary to mix samples from different instances.

  4. If ‘PresentationQosPolicy::access_scope’ is ‘GROUP_PRESENTATION_QOS’ and ‘PresentationQosPolicy::ordered_access’ is set to false, then the returned collection is a ‘list’ where samples belonging to the same data instance are consecutive.

  5. If ‘PresentationQosPolicy::access_scope’ is ‘GROUP_PRESENTATION_QOS’ and ‘PresentationQosPolicy::ordered_access’ is set to true, then the returned collection contains at most one sample. The difference in this case is due to the fact that it is required that the application is able to read samples belonging to different DataReader objects in a specific order.

In any case, the relative order between the samples of one instance is consistent with the ‘DestinationOrderQosPolicy’:

  • If ‘DestinationOrderQosPolicy::kind’ is ‘BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS’, samples belonging to the same instances will appear in the relative order in which there were received (FIFO, earlier samples ahead of the later samples).

  • If ‘DestinationOrderQosPolicy::kind’ is ‘BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS’, samples belonging to the same instances will appear in the relative order implied by the source_timestamp (FIFO, smaller values of source_timestamp ahead of the larger values).

The actual number of samples returned depends on the information that has been received by the middleware as well as the ‘HistoryQosPolicy’, ‘ResourceLimitsQosPolicy’, and ‘ReaderResourceLimitsQos’:

  • In the case where the ‘HistoryQosPolicy::kind’ is KEEP_LAST_HISTORY_QOS, the call will return at most ‘HistoryQosPolicy::depth’ samples per instance.

  • The maximum number of samples returned is limited by ‘ResourceLimitsQosPolicy::max_samples’, and by ‘ReaderResourceLimitsQos::max_samples_per_read’.

  • For multiple instances, the number of samples returned is additionally limited by the product (‘ResourceLimitsQosPolicy::max_samples_per_instance’ * ‘ResourceLimitsQosPolicy::max_instances)’.

  • If ReaderResourceLimitsQos::sample_infos_allocation has a maximum limit, the number of samples returned may also be limited if insufficient ‘SampleInfo’ resources are available.

If the operation succeeds and the number of samples returned has been limited (by means of a maximum limit, as listed above, or insufficient ‘SampleInfo’ resources), the call will complete successfully and provide those samples the reader is able to return. The user may need to make additional calls, or return outstanding loaned buffers in the case of insufficient resources, in order to access remaining samples.

In addition to the collection of samples, the read operation also uses a collection of ‘SampleInfo’ structures (sample_infos).

The initial (input) properties of the data_values and sample_infos collections will determine the precise behavior of this operation. For the purposes of this description the collections are modeled as having three properties:

  • the current length (len, see ‘LoanableCollection::length())’

  • the maximum length (max_len, see ‘LoanableCollection::maximum())’

  • whether the collection container owns the memory of the elements within (owns, see ‘LoanableCollection::has_ownership())’

The initial (input) values of the len, max_len, and owns properties for the data_values and sample_infos collections govern the behavior of the read operation as specified by the following rules:

  1. The values of len, max_len, and owns for the two collections must be identical. Otherwise read will fail with RETCODE_PRECONDITION_NOT_MET.

  2. On successful output, the values of len, max_len, and owns will be the same for both collections.

  3. If the input max_len == 0 , then the data_values and sample_infos collections will be filled with elements that are ‘loaned’ by the DataReader. On output, owns will be false, len will be set to the number of values returned, and max_len will be set to a value verifying max_len >= len . The use of this variant allows for zero-copy access to the data and the application will need to return the loan to the DataReader using the ‘return_loan’ operation.

  4. If the input max_len > 0 and the input owns == false , then the read operation will fail with RETCODE_PRECONDITION_NOT_MET. This avoids the potential hard-to-detect memory leaks caused by an application forgetting to return the loan.

  5. If input max_len > 0 and the input owns == true , then the read operation will copy the Data values and SampleInfo values into the elements already inside the collections. On output, owns will be true, len will be set to the number of values copied, and max_len will remain unchanged. The use of this variant forces a copy but the application can control where the copy is placed and the application will not need to return the loan. The number of samples copied depends on the values of max_len and max_samples:

    • If max_samples == LENGTH_UNLIMITED , then at most max_len values will be copied. The use of this variant lets the application limit the number of samples returned to what the sequence can accommodate.

    • If max_samples <= max_len , then at most max_samples values will be copied. The use of this variant lets the application limit the number of samples returned to fewer that what the sequence can accommodate.

    • If max_samples > max_len , then the read operation will fail with RETCODE_PRECONDITION_NOT_MET. This avoids the potential confusion where the application expects to be able to access up to max_samples, but that number can never be returned, even if they are available in the DataReader, because the output sequence cannot accommodate them.

As described above, upon return the data_values and sample_infos collections may contain elements ‘loaned’ from the DataReader. If this is the case, the application will need to use the ‘return_loan’ operation to return the loan once it is no longer using the Data in the collection. Upon return from ‘return_loan’, the collection will have max_len == 0 and owns == false .

The application can determine whether it is necessary to return the loan or not based on the state of the collections when the read operation was called, or by accessing the owns property. However, in many cases it may be simpler to always call ‘return_loan’, as this operation is harmless (i.e., leaves all elements unchanged) if the collection does not have a loan.

On output, the collection of Data values and the collection of SampleInfo structures are of the same length and are in a one-to-one correspondence. Each SampleInfo provides information, such as the source_timestamp, the sample_state, view_state, and instance_state, etc., about the corresponding sample.

Some elements in the returned collection may not have valid data. If the instance_state in the SampleInfo is ‘NOT_ALIVE_DISPOSED_INSTANCE_STATE’ or ‘NOT_ALIVE_NO_WRITERS_INSTANCE_STATE’, then the last sample for that instance in the collection, that is, the one whose SampleInfo has sample_rank == 0 does not contain valid data. Samples that contain no data do not count towards the limits imposed by the ‘ResourceLimitsQosPolicy’.

The act of reading a sample changes its sample_state to ‘READ_SAMPLE_STATE’. If the sample belongs to the most recent generation of the instance, it will also set the view_state of the instance to be ‘NOT_NEW_VIEW_STATE’. It will not affect the instance_state of the instance.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Important: If the samples “returned” by this method are loaned from the middleware (see ‘take’ for more information on memory loaning), it is important that their contents not be changed. Because the memory in which the data is stored belongs to the middleware, any modifications made to the data will be seen the next time the same samples are read or taken; the samples will no longer reflect the state that was received from the network.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are available, up to the limits described above.

  • [in] – sample_states Only data samples with sample_state matching one of these will be returned.

  • [in] – view_states Only data samples with view_state matching one of these will be returned.

  • [in] – instance_states Only data samples with instance_state matching one of these will be returned.

Return type:

int

Returns:

Any of the standard return codes.

read_instance(*args)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data values from the DataReader. The behavior is identical to ‘read’, except that all samples returned belong to the single specified instance whose handle is a_handle.

Upon successful completion, the data collection will contain samples all belonging to the same instance. The corresponding ‘SampleInfo’ verifies ‘SampleInfo::instance_handle’ == a_handle.

This operation is semantically equivalent to the ‘read’ operation, except in building the collection. The DataReader will check that the sample belongs to the specified instance and otherwise it will not place the sample in the returned collection.

The behavior of this operation follows the same rules as the ‘read’ operation regarding the pre-conditions and post-conditions for the data_values and sample_infos. Similar to ‘read’, this operation may ‘loan’ elements to the output collections, which must then be returned by means of ‘return_loan’.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are available, up to the limits described in the documentation for ‘read()’.

  • [in] – a_handle The specified instance to return samples for. The method will fail with RETCODE_BAD_PARAMETER if the handle does not correspond to an existing data-object known to the DataReader.

  • [in] – sample_states Only data samples with sample_state matching one of these will be returned.

  • [in] – view_states Only data samples with view_state matching one of these will be returned.

  • [in] – instance_states Only data samples with instance_state matching one of these will be returned.

Return type:

int

Returns:

Any of the standard return codes.

read_next_instance(*args)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data values from the DataReader where all the samples belong to a single instance. The behavior is similar to ‘read_instance’, except that the actual instance is not directly specified. Rather, the samples will all belong to the ‘next’ instance with instance_handle ‘greater’ than the specified ‘previous_handle’ that has available samples.

This operation implies the existence of a total order ‘greater-than’ relationship between the instance handles. The specifics of this relationship are not all important and are implementation specific. The important thing is that, according to the middleware, all instances are ordered relative to each other. This ordering is between the instance handles, and should not depend on the state of the instance (e.g. whether it has data or not) and must be defined even for instance handles that do not correspond to instances currently managed by the DataReader. For the purposes of the ordering, it should be ‘as if’ each instance handle was represented as an integer.

The behavior of this operation is ‘as if’ the DataReader invoked ‘read_instance’, passing the smallest instance_handle among all the ones that: (a) are greater than previous_handle, and (b) have available samples (i.e. samples that meet the constraints imposed by the specified states).

The special value ‘HANDLE_NIL’ is guaranteed to be ‘less than’ any valid instance_handle. So the use of the parameter value previous_handle == ‘HANDLE_NIL’ will return the samples for the instance which has the smallest instance_handle among all the instances that contain available samples.

This operation is intended to be used in an application-driven iteration, where the application starts by passing previous_handle == ‘HANDLE_NIL’, examines the samples returned, and then uses the instance_handle returned in the ‘SampleInfo’ as the value of the previous_handle argument to the next call to ‘read_next_instance’. The iteration continues until ‘read_next_instance’ fails with RETCODE_NO_DATA.

Note that it is possible to call the ‘read_next_instance’ operation with a previous_handle that does not correspond to an instance currently managed by the DataReader. This is because as stated earlier the ‘greater-than’ relationship is defined even for handles not managed by the DataReader. One practical situation where this may occur is when an application is iterating through all the instances, takes all the samples of a ‘NOT_ALIVE_NO_WRITERS_INSTANCE_STATE’ instance, returns the loan (at which point the instance information may be removed, and thus the handle becomes invalid), and tries to read the next instance.

The behavior of this operation follows the same rules as the ‘read’ operation regarding the pre-conditions and post-conditions for the data_values and sample_infos. Similar to ‘read’, this operation may ‘loan’ elements to the output collections, which must then be returned by means of ‘return_loan’.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are available, up to the limits described in the documentation for ‘read()’.

  • [in] – previous_handle The ‘next smallest’ instance with a value greater than this value that has available samples will be returned.

  • [in] – sample_states Only data samples with sample_state matching one of these will be returned.

  • [in] – view_states Only data samples with view_state matching one of these will be returned.

  • [in] – instance_states Only data samples with instance_state matching one of these will be returned.

Return type:

int

Returns:

Any of the standard return codes.

read_next_instance_w_condition(data_values, sample_infos, max_samples, previous_handle, a_condition)

This operation accesses a collection of Data values from the DataReader. The behavior is identical to ‘read_next_instance’ except that all samples returned satisfy the specified condition. In other words, on success all returned samples belong to the same instance, and the instance is the instance with ‘smallest’ instance_handle among the ones that verify (a) instance_handle >= previous_handle and (b) have samples for which the specified ReadCondition evaluates to TRUE.

Similar to the operation ‘read_next_instance’ it is possible to call ‘read_next_instance_w_condition’ with a previous_handle that does not correspond to an instance currently managed by the DataReader.

The behavior of the ‘read_next_instance_w_condition’ operation follows the same rules than the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos collections. Similar to read, the ‘read_next_instance_w_condition’ operation may ‘loan’ elements to the output collections which must then be returned by means of ‘return_loan’.

If the DataReader has no samples that meet the constraints, the return value will be RETCODE_NO_DATA.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are available, up to the limits described in the documentation for ‘read()’.

  • [in] – previous_handle The ‘next smallest’ instance with a value greater than this value that has available samples will be returned.

  • [in] – a_condition A ReadCondition that returned data_values must pass

Return type:

int

Returns:

Any of the standard return codes.

read_next_sample(data, info)

This operation copies the next, non-previously accessed Data value from the DataReader; the operation also copies the corresponding SampleInfo. The implied order among the samples stored in the DataReader is the same as for the read operation.

The read_next_sample operation is semantically equivalent to the read operation where the input Data sequence has max_length = 1 , the sample_states = NOT_READ_SAMPLE_STATE , the view_states = ANY_VIEW_STATE , and the instance_states = ANY_INSTANCE_STATE .

The read_next_sample operation provides a simplified API to ‘read’ samples avoiding the need for the application to manage sequences and specify states.

If there is no unread data in the DataReader, the operation will return RETCODE_NO_DATA and nothing is copied

Parameters:
  • [out] – data Data pointer to store the sample

  • [out] – info SampleInfo pointer to store the sample information

Return type:

int

Returns:

Any of the standard return codes.

read_w_condition(data_values, sample_infos, max_samples, a_condition)

This operation accesses via ‘read’ the samples that match the criteria specified in the ReadCondition. This operation is especially useful in combination with QueryCondition to filter data samples based on the content.

The specified ReadCondition must be attached to the DataReader; otherwise the operation will fail and return RETCODE_PRECONDITION_NOT_MET.

In case the ReadCondition is a ‘plain’ ReadCondition and not the specialized QueryCondition, the operation is equivalent to calling read and passing as sample_states, view_states and instance_states the value of the corresponding attributes in a_condition. Using this operation the application can avoid repeating the same parameters specified when creating the ReadCondition.

The samples are accessed with the same semantics as the read operation. If the DataReader has no samples that meet the constraints, the return value will be RETCODE_NO_DATA.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned.

  • [in] – a_condition A ReadCondition that returned data_values must pass

Return type:

int

Returns:

Any of the standard return codes.

return_loan(data_values, sample_infos)

This operation indicates to the DataReader that the application is done accessing the collection of data_values and sample_infos obtained by some earlier invocation of ‘read’ or ‘take’ on the DataReader.

The data_values and sample_infos must belong to a single related ‘pair’; that is, they should correspond to a pair returned from a single call to read or take. The data_values and sample_infos must also have been obtained from the same DataReader to which they are returned. If either of these conditions is not met, the operation will fail and return RETCODE_PRECONDITION_NOT_MET.

This operation allows implementations of the ‘read’ and ‘take’ operations to “loan” buffers from the DataReader to the application and in this manner provide “zero-copy” access to the data. During the loan, the DataReader will guarantee that the data and sample-information are not modified.

It is not necessary for an application to return the loans immediately after the read or take calls. However, as these buffers correspond to internal resources inside the DataReader, the application should not retain them indefinitely.

The use of the ‘return_loan’ operation is only necessary if the read or take calls “loaned” buffers to the application. This only occurs if the data_values and sample_infos collections had max_len == 0 at the time read or take was called. The application may also examine the has_ownership property of the collection to determine if there is an outstanding loan. However, calling ‘return_loan’ on a collection that does not have a loan is safe, has no side effects, and returns RETCODE_OK.

If the collections had a loan, upon return from return_loan the collections will have max_len == 0 .

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples were obtained from an earlier invocation of read or take on this DataReader.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample infos were obtained from an earlier invocation of read or take on this DataReader.

Return type:

int

Returns:

Any of the standard return codes.

set_listener(*args)
set_qos(qos)

Setter for the DataReaderQos.

Parameters:

[in] – qos new value for the DataReaderQos.

Return type:

int

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

take(*args)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data-samples from the DataReader and a corresponding collection of SampleInfo structures, and ‘removes’ them from the DataReader. The operation will return either a ‘list’ of samples or else a single sample. This is controlled by the ‘PresentationQosPolicy’ using the same logic as for the ‘read’ operation.

The act of taking a sample removes it from the DataReader so it cannot be ‘read’ or ‘taken’ again. If the sample belongs to the most recent generation of the instance, it will also set the view_state of the instance to NOT_NEW. It will not affect the instance_state of the instance.

The behavior of the take operation follows the same rules than the ‘read’ operation regarding the pre-conditions and post-conditions for the data_values and sample_infos collections. Similar to ‘read’, the take operation may ‘loan’ elements to the output collections which must then be returned by means of ‘return_loan’. The only difference with ‘read’ is that, as stated, the samples returned by take will no longer be accessible to successive calls to read or take.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are available, up to the limits described in the documentation for ‘read()’.

  • [in] – sample_states Only data samples with sample_state matching one of these will be returned.

  • [in] – view_states Only data samples with view_state matching one of these will be returned.

  • [in] – instance_states Only data samples with instance_state matching one of these will be returned.

Return type:

int

Returns:

Any of the standard return codes.

take_instance(*args)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data values from the DataReader and ‘removes’ them from the DataReader.

This operation has the same behavior as ‘read_instance’, except that the samples are ‘taken’ from the DataReader such that they are no longer accessible via subsequent ‘read’ or ‘take’ operations.

The behavior of this operation follows the same rules as the ‘read’ operation regarding the pre-conditions and post-conditions for the data_values and sample_infos. Similar to ‘read’, this operation may ‘loan’ elements to the output collections, which must then be returned by means of ‘return_loan’.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are available, up to the limits described in the documentation for ‘read()’.

  • [in] – a_handle The specified instance to return samples for. The method will fail with RETCODE_BAD_PARAMETER if the handle does not correspond to an existing data-object known to the DataReader.

  • [in] – sample_states Only data samples with sample_state matching one of these will be returned.

  • [in] – view_states Only data samples with view_state matching one of these will be returned.

  • [in] – instance_states Only data samples with instance_state matching one of these will be returned.

Return type:

int

Returns:

Any of the standard return codes.

take_next_instance(*args)

Access a collection of data samples from the DataReader.

This operation accesses a collection of data values from the DataReader and ‘removes’ them from the DataReader.

This operation has the same behavior as ‘read_next_instance’, except that the samples are ‘taken’ from the DataReader such that they are no longer accessible via subsequent ‘read’ or ‘take’ operations.

Similar to the operation ‘read_next_instance’, it is possible to call this operation with a previous_handle that does not correspond to an instance currently managed by the DataReader.

The behavior of this operation follows the same rules as the ‘read’ operation regarding the pre-conditions and post-conditions for the data_values and sample_infos. Similar to ‘read’, this operation may ‘loan’ elements to the output collections, which must then be returned by means of ‘return_loan’.

If the DataReader has no samples that meet the constraints, the operations fails with RETCODE_NO_DATA.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are available, up to the limits described in the documentation for ‘read()’.

  • [in] – previous_handle The ‘next smallest’ instance with a value greater than this value that has available samples will be returned.

  • [in] – sample_states Only data samples with sample_state matching one of these will be returned.

  • [in] – view_states Only data samples with view_state matching one of these will be returned.

  • [in] – instance_states Only data samples with instance_state matching one of these will be returned.

Return type:

int

Returns:

Any of the standard return codes.

take_next_instance_w_condition(data_values, sample_infos, max_samples, previous_handle, a_condition)

This operation accesses a collection of Data values from the DataReader. The behavior is identical to ‘read_next_instance’ except that all samples returned satisfy the specified condition. In other words, on success all returned samples belong to the same instance, and the instance is the instance with ‘smallest’ instance_handle among the ones that verify (a) instance_handle >= previous_handle and (b) have samples for which the specified ReadCondition evaluates to TRUE.

Similar to the operation ‘read_next_instance’ it is possible to call ‘read_next_instance_w_condition’ with a previous_handle that does not correspond to an instance currently managed by the DataReader.

The behavior of the ‘read_next_instance_w_condition’ operation follows the same rules than the read operation regarding the pre-conditions and post-conditions for the data_values and sample_infos collections. Similar to read, the ‘read_next_instance_w_condition’ operation may ‘loan’ elements to the output collections which must then be returned by means of ‘return_loan’.

If the DataReader has no samples that meet the constraints, the return value will be RETCODE_NO_DATA

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are available, up to the limits described in the documentation for ‘read()’.

  • [in] – previous_handle The ‘next smallest’ instance with a value greater than this value that has available samples will be returned.

  • [in] – a_condition A ReadCondition that returned data_values must pass

Return type:

int

Returns:

Any of the standard return codes.

take_next_sample(data, info)

This operation copies the next, non-previously accessed Data value from the DataReader and ‘removes’ it from the DataReader so it is no longer accessible. The operation also copies the corresponding SampleInfo.

This operation is analogous to ‘read_next_sample’ except for the fact that the sample is ‘removed’ from the DataReader.

This operation is semantically equivalent to the ‘take’ operation where the input sequence has

max_length = 1 , the sample_states = NOT_READ_SAMPLE_STATE , the view_states = ANY_VIEW_STATE , and the instance_states = ANY_INSTANCE_STATE .

This operation provides a simplified API to ’take’ samples avoiding the need for the application to manage sequences and specify states.

If there is no unread data in the DataReader, the operation will return RETCODE_NO_DATA and nothing is copied.

Parameters:
  • [out] – data Data pointer to store the sample

  • [out] – info SampleInfo pointer to store the sample information

Return type:

int

Returns:

Any of the standard return codes.

take_w_condition(data_values, sample_infos, max_samples, a_condition)

This operation is analogous to ‘read_w_condition’ except it accesses samples via the ‘take’ operation.

The specified ReadCondition must be attached to the DataReader; otherwise the operation will fail and return RETCODE_PRECONDITION_NOT_MET.

The samples are accessed with the same semantics as the ‘take’ operation.

This operation is especially useful in combination with QueryCondition to filter data samples based on the content.

If the DataReader has no samples that meet the constraints, the return value will be RETCODE_NO_DATA.

Parameters:
  • [in,out] – data_values A LoanableCollection object where the received data samples will be returned.

  • [in,out] – sample_infos A SampleInfoSeq object where the received sample info will be returned.

  • [in] – max_samples The maximum number of samples to be returned. If the special value ‘LENGTH_UNLIMITED’ is provided, as many samples will be returned as are.

  • [in] – a_condition A ReadCondition that returned data_values must pass

Return type:

int

Returns:

Any of the standard return codes.

property thisown

The membership flag

type()

Getter for the data type.

Return type:

TypeSupport

Returns:

Copy of the TypeSupport associated to the DataReader.

wait_for_historical_data(max_wait)

NOT YET IMPLEMENTED

Method to block the current thread until an unread message is available.

Parameters:

[in] – max_wait Max blocking time for this operation.

Return type:

int

Returns:

RETCODE_OK if there is new unread message, RETCODE_TIMEOUT if timeout

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

wait_for_unread_message(timeout)

Method to block the current thread until an unread message is available.

Parameters:

[in] – timeout Max blocking time for this operation.

Return type:

boolean

Returns:

true if there is new unread message, false if timeout

21.1.4.2. DataReaderListener
class fastdds.DataReaderListener

Class DataReaderListener, it should be used by the end user to implement specific callbacks to certain actions.

on_data_available(reader)

Virtual function to be implemented by the user containing the actions to be performed when new Data Messages are received.

Parameters:

reader (DataReader) – DataReader

on_liveliness_changed(reader, status)

Method called when the liveliness status associated to a subscriber changes

Parameters:
on_requested_deadline_missed(reader, status)

Virtual method to be called when a topic misses the deadline period

Parameters:
  • reader (DataReader) – DataReader

  • status (RequestedDeadlineMissedStatus) – The requested deadline missed status

on_requested_incompatible_qos(reader, status)

Method called an incompatible QoS was requested.

Parameters:
  • reader (DataReader) – The DataReader

  • status (RequestedIncompatibleQosStatus) – The requested incompatible QoS status

on_sample_lost(reader, status)

Method called when a sample was lost.

Parameters:
  • reader (DataReader) – The DataReader

  • status (SampleLostStatus) – The sample lost status

on_sample_rejected(reader, status)

Method called when a sample was rejected.

Parameters:
on_subscription_matched(reader, info)

Virtual method to be called when the subscriber is matched with a new Writer (or unmatched); i.e., when a writer publishing in the same topic is discovered.

Parameters:
property thisown

The membership flag

21.1.4.3. DataReaderQos
class fastdds.DataReaderQos

Class DataReaderQos, containing all the possible Qos that can be set for a determined DataReader. Although these values can be set and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

data_sharing(*args)

Overload 1:

Getter for DataSharingQosPolicy

Return type:

DataSharingQosPolicy

Returns:

DataSharingQosPolicy reference


Overload 2:

Getter for DataSharingQosPolicy

Return type:

DataSharingQosPolicy

Returns:

DataSharingQosPolicy reference


Overload 3:

Setter for DataSharingQosPolicy

Parameters:

data_sharing (DataSharingQosPolicy) – new value for the DataSharingQosPolicy

deadline(*args)

Overload 1:

Getter for DeadlineQosPolicy

Return type:

DeadlineQosPolicy

Returns:

DeadlineQosPolicy reference


Overload 2:

Getter for DeadlineQosPolicy

Return type:

DeadlineQosPolicy

Returns:

DeadlineQosPolicy const reference


Overload 3:

Setter for DeadlineQosPolicy

Parameters:

new_value (DeadlineQosPolicy) – new value for the DeadlineQosPolicy

destination_order(*args)

Overload 1:

Getter for DestinationOrderQosPolicy

Return type:

DestinationOrderQosPolicy

Returns:

DestinationOrderQosPolicy reference


Overload 2:

Getter for DestinationOrderQosPolicy

Return type:

DestinationOrderQosPolicy

Returns:

DestinationOrderQosPolicy const reference


Overload 3:

Setter for DestinationOrderQosPolicy

Parameters:

new_value (DestinationOrderQosPolicy) – new value for the DestinationOrderQosPolicy

durability(*args)

Overload 1:

Getter for DurabilityQosPolicy

Return type:

DurabilityQosPolicy

Returns:

DurabilityQosPolicy reference


Overload 2:

Getter for DurabilityQosPolicy

Return type:

DurabilityQosPolicy

Returns:

DurabilityQosPolicy const reference


Overload 3:

Setter for DurabilityQosPolicy

Parameters:

new_value (DurabilityQosPolicy) – new value for the DurabilityQosPolicy

durability_service(*args)

Overload 1:

Getter for DurabilityServiceQosPolicy

Return type:

DurabilityServiceQosPolicy

Returns:

DurabilityServiceQosPolicy reference


Overload 2:

Getter for DurabilityServiceQosPolicy

Return type:

DurabilityServiceQosPolicy

Returns:

DurabilityServiceQosPolicy const reference


Overload 3:

Setter for DurabilityServiceQosPolicy

Parameters:

new_value (DurabilityServiceQosPolicy) – new value for the DurabilityServiceQosPolicy

endpoint(*args)

Overload 1:

Getter for RTPSEndpointQos

Return type:

RTPSEndpointQos

Returns:

RTPSEndpointQos reference


Overload 2:

Getter for RTPSEndpointQos

Return type:

RTPSEndpointQos

Returns:

RTPSEndpointQos const reference


Overload 3:

Setter for RTPSEndpointQos

Parameters:

new_value (RTPSEndpointQos) – new value for the RTPSEndpointQos

expects_inline_qos(*args)

Overload 1:

Getter for expects_inline_qos

Return type:

boolean

Returns:

expects_inline_qos


Overload 2:

Setter for expects_inline_qos

Parameters:

new_value (boolean) – new value for the expects_inline_qos

get_readerqos(sqos)
history(*args)

Overload 1:

Getter for HistoryQosPolicy

Return type:

HistoryQosPolicy

Returns:

HistoryQosPolicy reference


Overload 2:

Getter for HistoryQosPolicy

Return type:

HistoryQosPolicy

Returns:

HistoryQosPolicy const reference


Overload 3:

Setter for HistoryQosPolicy

Parameters:

new_value (HistoryQosPolicy) – new value for the HistoryQosPolicy

latency_budget(*args)

Overload 1:

Getter for LatencyBudgetQosPolicy

Return type:

LatencyBudgetQosPolicy

Returns:

LatencyBudgetQosPolicy reference


Overload 2:

Getter for LatencyBudgetQosPolicy

Return type:

LatencyBudgetQosPolicy

Returns:

LatencyBudgetQosPolicy const reference


Overload 3:

Setter for LatencyBudgetQosPolicy

Parameters:

new_value (LatencyBudgetQosPolicy) – new value for the LatencyBudgetQosPolicy

lifespan(*args)

Overload 1:

Getter for LifespanQosPolicy

Return type:

LifespanQosPolicy

Returns:

LifespanQosPolicy reference


Overload 2:

Getter for LifespanQosPolicy

Return type:

LifespanQosPolicy

Returns:

LifespanQosPolicy const reference


Overload 3:

Setter for LifespanQosPolicy

Parameters:

new_value (LifespanQosPolicy) – new value for the LifespanQosPolicy

liveliness(*args)

Overload 1:

Getter for LivelinessQosPolicy

Return type:

LivelinessQosPolicy

Returns:

LivelinessQosPolicy reference


Overload 2:

Getter for LivelinessQosPolicy

Return type:

LivelinessQosPolicy

Returns:

LivelinessQosPolicy const reference


Overload 3:

Setter for LivelinessQosPolicy

Parameters:

new_value (LivelinessQosPolicy) – new value for the LivelinessQosPolicy

ownership(*args)

Overload 1:

Getter for OwnershipQosPolicy

Return type:

OwnershipQosPolicy

Returns:

OwnershipQosPolicy reference


Overload 2:

Getter for OwnershipQosPolicy

Return type:

OwnershipQosPolicy

Returns:

OwnershipQosPolicy const reference


Overload 3:

Setter for OwnershipQosPolicy

Parameters:

new_value (OwnershipQosPolicy) – new value for the OwnershipQosPolicy

properties(*args)

Overload 1:

Getter for PropertyPolicyQos

Return type:

PropertyPolicyQos

Returns:

PropertyPolicyQos reference


Overload 2:

Getter for PropertyPolicyQos

Return type:

PropertyPolicyQos

Returns:

PropertyPolicyQos const reference


Overload 3:

Setter for PropertyPolicyQos

Parameters:

new_value (PropertyPolicyQos) – new value for the PropertyPolicyQos

reader_data_lifecycle(*args)

Overload 1:

Getter for ReaderDataLifecycleQosPolicy

Return type:

ReaderDataLifecycleQosPolicy

Returns:

ReaderDataLifecycleQosPolicy reference


Overload 2:

Getter for ReaderDataLifecycleQosPolicy

Return type:

ReaderDataLifecycleQosPolicy

Returns:

ReaderDataLifecycleQosPolicy const reference


Overload 3:

Setter for ReaderDataLifecycleQosPolicy

Parameters:

new_value (ReaderDataLifecycleQosPolicy) – new value for the ReaderDataLifecycleQosPolicy

reader_resource_limits(*args)

Overload 1:

Getter for ReaderResourceLimitsQos

Return type:

ReaderResourceLimitsQos

Returns:

ReaderResourceLimitsQos reference


Overload 2:

Getter for ReaderResourceLimitsQos

Return type:

ReaderResourceLimitsQos

Returns:

ReaderResourceLimitsQos const reference


Overload 3:

Setter for ReaderResourceLimitsQos

Parameters:

new_value (ReaderResourceLimitsQos) – new value for the ReaderResourceLimitsQos

reliability(*args)

Overload 1:

Getter for ReliabilityQosPolicy

Return type:

ReliabilityQosPolicy

Returns:

ReliabilityQosPolicy reference


Overload 2:

Getter for ReliabilityQosPolicy

Return type:

ReliabilityQosPolicy

Returns:

ReliabilityQosPolicy const reference


Overload 3:

Setter for ReliabilityQosPolicy

Parameters:

new_value (ReliabilityQosPolicy) – new value for the ReliabilityQosPolicy

reliable_reader_qos(*args)

Overload 1:

Getter for RTPSReliableReaderQos

Return type:

RTPSReliableReaderQos

Returns:

RTPSReliableReaderQos reference


Overload 2:

Getter for RTPSReliableReaderQos

Return type:

RTPSReliableReaderQos

Returns:

RTPSReliableReaderQos const reference


Overload 3:

Setter for RTPSReliableReaderQos

Parameters:

new_value (RTPSReliableReaderQos) – new value for the RTPSReliableReaderQos

representation(*args)

Overload 1:

Getter for DataRepresentationQosPolicy

Return type:

DataRepresentationQosPolicy

Returns:

DataRepresentationQosPolicy reference


Overload 2:

Getter for DataRepresentationQosPolicy

Return type:

DataRepresentationQosPolicy

Returns:

DataRepresentationQosPolicy reference


Overload 3:

Setter for DataRepresentationQosPolicy

Parameters:

representation (DataRepresentationQosPolicy) – new value for the DataRepresentationQosPolicy

resource_limits(*args)

Overload 1:

Getter for ResourceLimitsQosPolicy

Return type:

ResourceLimitsQosPolicy

Returns:

ResourceLimitsQosPolicy reference


Overload 2:

Getter for ResourceLimitsQosPolicy

Return type:

ResourceLimitsQosPolicy

Returns:

ResourceLimitsQosPolicy const reference


Overload 3:

Setter for ResourceLimitsQosPolicy

Parameters:

new_value (ResourceLimitsQosPolicy) – new value for the ResourceLimitsQosPolicy

property thisown

The membership flag

time_based_filter(*args)

Overload 1:

Getter for TimeBasedFilterQosPolicy

Return type:

TimeBasedFilterQosPolicy

Returns:

TimeBasedFilterQosPolicy reference


Overload 2:

Getter for TimeBasedFilterQosPolicy

Return type:

TimeBasedFilterQosPolicy

Returns:

TimeBasedFilterQosPolicy const reference


Overload 3:

Setter for TimeBasedFilterQosPolicy

Parameters:

new_value (TimeBasedFilterQosPolicy) – new value for the TimeBasedFilterQosPolicy

type_consistency(*args)

Overload 1:

Getter for TypeConsistencyEnforcementQosPolicy

Return type:

TypeConsistencyEnforcementQosPolicy

Returns:

TypeConsistencyEnforcementQosPolicy reference


Overload 2:

Getter for TypeConsistencyEnforcementQosPolicy

Return type:

TypeConsistencyEnforcementQosPolicy

Returns:

TypeConsistencyEnforcementQosPolicy const reference


Overload 3:

Setter for TypeConsistencyEnforcementQosPolicy

Parameters:

new_value (TypeConsistencyEnforcementQosPolicy) – new value for the TypeConsistencyEnforcementQosPolicy

user_data(*args)

Overload 1:

Getter for UserDataQosPolicy

Return type:

UserDataQosPolicy

Returns:

UserDataQosPolicy reference


Overload 2:

Getter for UserDataQosPolicy

Return type:

UserDataQosPolicy

Returns:

UserDataQosPolicy const reference


Overload 3:

Setter for UserDataQosPolicy

Parameters:

new_value (UserDataQosPolicy) – new value for the UserDataQosPolicy

fastdds.DATAREADER_QOS_DEFAULT = <fastdds.DataReaderQos>
fastdds.DATAREADER_QOS_USE_TOPIC_QOS = <fastdds.DataReaderQos>
21.1.4.4. InstanceStateKind
class fastdds.ALIVE_INSTANCE_STATE(*args: Any, **kwargs: Any)
class fastdds.NOT_ALIVE_DISPOSED_INSTANCE_STATE(*args: Any, **kwargs: Any)
class fastdds.NOT_ALIVE_NO_WRITERS_INSTANCE_STATE(*args: Any, **kwargs: Any)
21.1.4.5. ReaderResourceLimitsQos
class fastdds.ReaderResourceLimitsQos

Qos Policy to configure the limit of the reader resources

clear()
property matched_publisher_allocation

Matched publishers allocation limits.

property max_samples_per_read

Maximum number of samples to return on a single call to read / take.

This attribute is a signed integer to be consistent with the max_samples argument of ‘DataReader’ methods, but should always have a strict positive value. Bear in mind that a big number here may cause the creation of the DataReader to fail due to pre-allocation of internal resources.

Default value: 32.

property outstanding_reads_allocation

Loaned collections allocation limits.

property sample_infos_allocation

SampleInfo allocation limits.

property thisown

The membership flag

21.1.4.6. RTPSReliableReaderQos
class fastdds.RTPSReliableReaderQos

Qos Policy to configure the DisablePositiveACKsQos and the reader attributes

clear()
property disable_positive_acks

Control the sending of positive ACKs

property thisown

The membership flag

property times

Times associated with the Reliable Readers events.

21.1.4.7. SampleInfo
class fastdds.SampleInfo

SampleInfo is the information that accompanies each sample that is ‘read’ or ‘taken.’

property absolute_generation_rank

the generation difference between the time the sample was received, and the time the most recent sample was received. The most recent sample used for the calculation may or may not be in the returned collection

property disposed_generation_count

number of times the instance had become alive after it was disposed

property generation_rank

the generation difference between the time the sample was received, and the time the most recent sample in the collection was received.

property instance_handle

identifies locally the corresponding instance

property instance_state

indicates whether the instance is currently in existence or, if it has been disposed, the reason why it was disposed.

property no_writers_generation_count

number of times the instance had become alive after it was disposed because no writers

property publication_handle

identifies locally the DataWriter that modified the instance Is the same InstanceHandle_t that is returned by the operation get_matched_publications on the DataReader

property reception_timestamp

time provided by the DataReader when the sample was added to its history

property related_sample_identity

Related Sample Identity (Extension for RPC)

property sample_identity

Sample Identity (Extension for RPC)

property sample_rank

number of samples related to the same instance that follow in the collection

property sample_state

indicates whether or not the corresponding data sample has already been read

property source_timestamp

time provided by the DataWriter when the sample was written

property thisown

The membership flag

property valid_data

whether the DataSample contains data or is only used to communicate of a change in the instance

property view_state

indicates whether the DataReader has already seen samples for the most-current generation of the related instance.

21.1.4.8. SampleStateKind
class fastdds.READ_SAMPLE_STATE(*args: Any, **kwargs: Any)
class fastdds.NOT_READ_SAMPLE_STATE(*args: Any, **kwargs: Any)
21.1.4.9. Subscriber
class fastdds.Subscriber(*args, **kwargs)

Class Subscriber, contains the public API that allows the user to control the reception of messages. This class should not be instantiated directly. DomainRTPSParticipant class should be used to correctly create this element.

begin_access()

Indicates that the application is about to access the data samples in any of the DataReader objects attached to the Subscriber.

Return type:

int

Returns:

RETCODE_OK

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

static copy_from_topic_qos(reader_qos, topic_qos)

Copies TopicQos into the corresponding DataReaderQos

:param [in:, out] reader_qos :param [in]: topic_qos :rtype: int :return: RETCODE_OK if successful, an error code otherwise

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

create_datareader(*args)

This operation creates a DataReader. The returned DataReader will be attached and belong to the Subscriber.

Parameters:
  • topic (TopicDescription) – Topic the DataReader will be listening.

  • reader_qos (DataReaderQos) – QoS of the DataReader.

  • listener (DataReaderListener) – Pointer to the listener (default: nullptr)

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all).

Return type:

DataReader

Returns:

Pointer to the created DataReader. nullptr if failed.

create_datareader_with_profile(*args)

This operation creates a DataReader. The returned DataReader will be attached and belongs to the Subscriber.

Parameters:
  • topic (TopicDescription) – Topic the DataReader will be listening.

  • profile_name (string) – DataReader profile name.

  • listener (DataReaderListener) – Pointer to the listener (default: nullptr)

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all).

Return type:

DataReader

Returns:

Pointer to the created DataReader. nullptr if failed.

delete_contained_entities()

Deletes all contained DataReaders. If the DataReaders have any QueryCondition or ReadCondition, they are deleted before the DataReader itself.

Return type:

int

Returns:

RETCODE_OK if successful, an error code otherwise

delete_datareader(reader)

This operation deletes a DataReader that belongs to the Subscriber.

The delete_datareader operation must be called on the same Subscriber object used to create the DataReader. If delete_datareader is called on a different Subscriber, the operation will have no effect and it will return an error.

Parameters:

reader (DataReader) – DataReader to delete

Return type:

int

Returns:

RETCODE_PRECONDITION_NOT_MET if the datareader does not belong to this subscriber, RETCODE_OK if it is correctly deleted and RETCODE_ERROR otherwise.

enable()

This operation enables the Subscriber

Return type:

int

Returns:

RETCODE_OK is successfully enabled. RETCODE_PRECONDITION_NOT_MET if the participant creating this Subscriber is not enabled.

end_access()

Indicates that the application has finished accessing the data samples in DataReader objects managed by the Subscriber.

Return type:

int

Returns:

RETCODE_OK

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_datareader_qos_from_profile(*args)

Overload 1:

Fills the ‘DataReaderQos’ with the values of the XML profile.

Parameters:
  • profile_name (string) – DataReader profile name.

  • qos (DataReaderQos) – ‘DataReaderQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘DataReaderQos’ with the values of the XML profile, and also its corresponding topic name (if specified).

Parameters:
  • profile_name (string) – DataReader profile name.

  • qos (DataReaderQos) – ‘DataReaderQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ if the profile exists. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_datareader_qos_from_xml(*args)

Overload 1:

Fills the ‘DataReaderQos’ with the first DataReader profile found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataReaderQos) – ‘DataReaderQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘DataReaderQos’ with the first DataReader profile found in the provided XML, and also its corresponding topic name (if specified).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataReaderQos) – ‘DataReaderQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 3:

Fills the ‘DataReaderQos’ with the DataReader profile with profile_name to be found in the provided XML.

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataReaderQos) – ‘DataReaderQos’ object where the qos is returned.

  • profile_name (string) – DataReader profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 4:

Fills the ‘DataReaderQos’ with the DataReader profile with profile_name to be found in the provided XML, and also its corresponding topic name (if specified).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataReaderQos) – ‘DataReaderQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

  • profile_name (string) – DataReader profile name.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_datareaders(*args)

Overload 1:

This operation allows the application to access the DataReader objects.

Parameters:

readers (DataReaderVector) – Vector of DataReader where the list of existing readers is returned

Return type:

int

Returns:

RETCODE_OK


Overload 2:

This operation allows the application to access the DataReader objects that contain samples with the specified sample_states, view_states, and instance_states.

Parameters:
  • [out] – readers Vector of DataReader where the list of existing readers is returned

  • sample_states (std::vector< eprosima::fastdds::dds::SampleStateKind,std::allocator< eprosima::fastdds::dds::SampleStateKind > >) – Vector of SampleStateKind

  • view_states (std::vector< eprosima::fastdds::dds::ViewStateKind,std::allocator< eprosima::fastdds::dds::ViewStateKind > >) – Vector of ViewStateKind

  • instance_states (std::vector< eprosima::fastdds::dds::InstanceStateKind,std::allocator< eprosima::fastdds::dds::InstanceStateKind > >) – Vector of InstanceStateKind

Return type:

int

Returns:

RETCODE_OK

Warning: Not supported yet. Currently returns RETCODE_UNSUPPORTED

get_default_datareader_qos(*args)

Overload 1:

This operation returns the default value of the DataReader QoS, that is, the QoS policies which will be used for newly created DataReader entities in the case where the QoS policies are defaulted in the create_datareader operation.

The values retrieved get_default_datareader_qos will match the set of values specified on the last successful call to get_default_datareader_qos, or else, if the call was never made, the default values.

Return type:

DataReaderQos

Returns:

Current default DataReaderQos.


Overload 2:

This operation returns the default value of the DataReader QoS, that is, the QoS policies which will be used for newly created DataReader entities in the case where the QoS policies are defaulted in the create_datareader operation.

The values retrieved get_default_datareader_qos will match the set of values specified on the last successful call to get_default_datareader_qos, or else, if the call was never made, the default values.

Return type:

DataReaderQos

Returns:

Current default DataReaderQos.


Overload 3:

This operation retrieves the default value of the DataReader QoS, that is, the QoS policies which will be used for newly created DataReader entities in the case where the QoS policies are defaulted in the create_datareader operation.

The values retrieved get_default_datareader_qos will match the set of values specified on the last successful call to get_default_datareader_qos, or else, if the call was never made, the default values.

Parameters:

qos (DataReaderQos) – DataReaderQos where the default_qos is returned

Return type:

int

Returns:

RETCODE_OK

get_default_datareader_qos_from_xml(*args)

Overload 1:

Fills the ‘DataReaderQos’ with the default DataReader profile found in the provided XML (if there is).

Notes: This method does not update the default datareader qos (returned by get_default_datareader_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataReaderQos) – ‘DataReaderQos’ object where the qos is returned.

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.


Overload 2:

Fills the ‘DataReaderQos’ with the default DataReader profile found in the provided XML (if there is), and also its corresponding topic name (if specified).

Notes: This method does not update the default datareader qos (returned by get_default_datareader_qos).

Parameters:
  • xml (string) – Raw XML string containing the profile to be used to fill the qos structure.

  • qos (DataReaderQos) – ‘DataReaderQos’ object where the qos is returned.

  • topic_name (string) – String where the name of the topic associated to this profile is returned (if specified).

Return type:

int

Returns:

‘RETCODE_OK’ on success. ‘RETCODE_BAD_PARAMETER’ otherwise.

get_instance_handle()

Returns the Subscriber’s handle.

Return type:

InstanceHandle_t

Returns:

InstanceHandle of this Subscriber.

get_listener()

Retrieves the attached SubscriberListener.

Return type:

SubscriberListener

Returns:

Pointer to the SubscriberListener

get_participant()

This operation returns the DomainParticipant to which the Subscriber belongs.

Return type:

DomainParticipant

Returns:

DomainParticipant Pointer

get_qos(*args)

Overload 1:

Allows accessing the Subscriber Qos.

Return type:

SubscriberQos

Returns:

SubscriberQos reference


Overload 2:

Retrieves the Subscriber Qos.

Parameters:

qos (SubscriberQos) – SubscriberQos where the qos is returned

Return type:

int

Returns:

RETCODE_OK

has_datareaders()

This operation checks if the subscriber has DataReaders

Return type:

boolean

Returns:

true if the subscriber has one or several DataReaders, false in other case

lookup_datareader(topic_name)

This operation retrieves a previously-created DataReader belonging to the Subscriber that is attached to a Topic with a matching topic_name. If no such DataReader exists, the operation will return nullptr.

If multiple DataReaders attached to the Subscriber satisfy this condition, then the operation will return one of them. It is not specified which one.

Parameters:

topic_name (string) – Name of the topic associated to the DataReader

Return type:

DataReader

Returns:

Pointer to a previously created DataReader created on a Topic with that topic_name

notify_datareaders()

This operation invokes the operation on_data_available on the DataReaderListener objects attached to contained DataReader entities.

This operation is typically invoked from the on_data_on_readers operation in the SubscriberListener. That way the SubscriberListener can delegate to the DataReaderListener objects the handling of the data.

Return type:

int

Returns:

RETCODE_OK

set_default_datareader_qos(qos)

This operation sets a default value of the DataReader QoS policies which will be used for newly created DataReader entities in the case where the QoS policies are defaulted in the create_datareader operation.

This operation will check that the resulting policies are self consistent; if they are not, the operation will have no effect and return false.

The special value DATAREADER_QOS_DEFAULT may be passed to this operation to indicate that the default QoS should be reset back to the initial values the factory would use, that is the values that would be used if the set_default_datareader_qos operation had never been called.

Parameters:

qos (DataReaderQos) – new value for DataReaderQos to set as default

Return type:

int

Returns:

RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

set_listener(*args)

Overload 1:

Modifies the SubscriberListener, sets the mask to StatusMask::all()

Parameters:

listener (SubscriberListener) – new value for SubscriberListener

Return type:

int

Returns:

RETCODE_OK


Overload 2:

Modifies the SubscriberListener.

Parameters:
  • listener (SubscriberListener) – new value for the SubscriberListener

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to.

Return type:

int

Returns:

RETCODE_OK

set_qos(qos)

Allows modifying the Subscriber Qos. The given Qos must be supported by the SubscriberQos.

Parameters:

qos (SubscriberQos) – new value for SubscriberQos

Return type:

int

Returns:

RETCODE_IMMUTABLE_POLICY if any of the Qos cannot be changed, RETCODE_INCONSISTENT_POLICY if the Qos is not self consistent and RETCODE_OK if the qos is changed correctly.

property thisown

The membership flag

21.1.4.10. SubscriberListener
class fastdds.SubscriberListener

Class SubscriberListener, it should be used by the end user to implement specific callbacks to certain actions. It also inherits all DataReaderListener callbacks.

on_data_on_readers(sub)

Virtual function to be implemented by the user containing the actions to be performed when a new Data Message is available on any reader.

Parameters:

sub (Subscriber) – Subscriber

property thisown

The membership flag

21.1.4.11. SubscriberQos
class fastdds.SubscriberQos

Class SubscriberQos, contains all the possible Qos that can be set for a determined Subscriber. Although these values can be set and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

entity_factory(*args)

Overload 1:

Getter for EntityFactoryQosPolicy

Return type:

EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference


Overload 2:

Getter for EntityFactoryQosPolicy

Return type:

EntityFactoryQosPolicy

Returns:

EntityFactoryQosPolicy reference


Overload 3:

Setter for EntityFactoryQosPolicy

Parameters:

entity_factory (EntityFactoryQosPolicy) – new value for the EntityFactoryQosPolicy

group_data(*args)

Overload 1:

Getter for GroupDataQosPolicy

Return type:

GroupDataQosPolicy

Returns:

GroupDataQosPolicy reference


Overload 2:

Getter for GroupDataQosPolicy

Return type:

GroupDataQosPolicy

Returns:

GroupDataQosPolicy reference


Overload 3:

Setter for GroupDataQosPolicy

Parameters:

group_data (GroupDataQosPolicy) – new value for the GroupDataQosPolicy

partition(*args)

Overload 1:

Getter for PartitionQosPolicy

Return type:

PartitionQosPolicy

Returns:

PartitionQosPolicy reference


Overload 2:

Getter for PartitionQosPolicy

Return type:

PartitionQosPolicy

Returns:

PartitionQosPolicy reference


Overload 3:

Setter for PartitionQosPolicy

Parameters:

partition (PartitionQosPolicy) – new value for the PartitionQosPolicy

presentation(*args)

Overload 1:

Getter for PresentationQosPolicy

Return type:

PresentationQosPolicy

Returns:

PresentationQosPolicy reference


Overload 2:

Getter for PresentationQosPolicy

Return type:

PresentationQosPolicy

Returns:

PresentationQosPolicy reference


Overload 3:

Setter for PresentationQosPolicy

Parameters:

presentation (PresentationQosPolicy) – new value for the PresentationQosPolicy

property thisown

The membership flag

fastdds.SUBSCRIBER_QOS_DEFAULT = <fastdds.SubscriberQos>
21.1.4.12. ViewStateKind
class fastdds.NEW_VIEW_STATE(*args: Any, **kwargs: Any)
class fastdds.NOT_NEW_VIEW_STATE(*args: Any, **kwargs: Any)

21.1.5. Topic

21.1.5.1. Topic
class fastdds.Topic(*args, **kwargs)

Class Topic, represents the fact that both publications and subscriptions are tied to a single data-type

get_impl()
get_listener()

Retrieves the attached TopicListener.

Return type:

TopicListener

Returns:

pointer to TopicListener

get_participant()

Getter for the DomainParticipant

Return type:

DomainParticipant

Returns:

DomainParticipant pointer

get_qos(*args)

Overload 1:

Allows accessing the Topic Qos.

Return type:

TopicQos

Returns:

reference to TopicQos


Overload 2:

Retrieves the Topic Qos.

Parameters:

qos (TopicQos) – TopicQos where the qos is returned

Return type:

int

Returns:

RETCODE_OK

set_listener(*args)

Modifies the TopicListener.

Parameters:
  • listener (TopicListener) – new value for the TopicListener

  • mask (StatusMask) – StatusMask that holds statuses the listener responds to (default: all).

Return type:

int

Returns:

RETCODE_OK

set_qos(qos)

Allows modifying the Topic Qos. The given Qos must be supported by the Topic.

Parameters:

qos (TopicQos) – new TopicQos value to set for the Topic.

property thisown

The membership flag

21.1.5.2. TopicDataType
class fastdds.TopicDataType(*args, **kwargs)

Class TopicDataType used to provide the DomainRTPSParticipant with the methods to serialize, deserialize and get the key of a specific data type. The user should created a class that inherits from this one, where Serialize and deserialize methods MUST be implemented.

calculate_serialized_size(data, data_representation)

Calculates the serialized size of the provided data.

Parameters:
  • [in] – data Pointer to data.

  • [in] – data_representation Representation that should be used for calculating the serialized size.

Return type:

int

Returns:

Serialized size of the data.

compute_key(*args)

Overload 1:

Get the key associated with the data.

Parameters:
  • [in] – payload Pointer to the payload containing the data.

  • [out] – ihandle Pointer to the Handle.

  • [in] – force_md5 Force MD5 checking.

Return type:

boolean

Returns:

True if correct.


Overload 2:

Get the key associated with the data.

Parameters:
  • [in] – data Pointer to the data.

  • [out] – ihandle Pointer to the Handle.

  • [in] – force_md5 Force MD5 checking.

Return type:

boolean

Returns:

True if correct.


Overload 3:

Get the key associated with the data.

Parameters:
  • [in] – data Pointer to the data.

  • [out] – ihandle Pointer to the Handle.

  • [in] – force_md5 Force MD5 checking.

Return type:

boolean

Returns:

True if correct.

construct_sample(memory)

Construct a sample on a memory location.

Parameters:

memory (void) – Pointer to the memory location where the sample should be constructed.

Return type:

boolean

Returns:

whether this type supports in-place construction or not.

create_data()

Create a Data Type.

Return type:

void

Returns:

Void pointer to the created object.

delete_data(data)

Remove a previously created object.

Parameters:

data (void) – Pointer to the created Data.

deserialize(payload, data)

Deserialize method, it should be implemented by the user, since it is abstract.

Parameters:
  • [in] – payload Pointer to the payload

  • [out] – data Pointer to the data

Return type:

boolean

Returns:

True if correct.

get_name()

Get topic data type name

Return type:

string

Returns:

Topic data type name

is_bounded()

Checks if the type is bounded.

property is_compute_key_provided

Indicates whether the method to obtain the key has been implemented.

is_plain(arg2)

Checks if the type is plain when using a specific encoding.

property max_serialized_type_size

Maximum serialized size of the type in bytes. If the type has unbounded fields, and therefore cannot have a maximum size, use 0.

register_type_object_representation()

Register TypeObject type representation

serialize(data, payload, data_representation)

Serialize method, it should be implemented by the user, since it is abstract. If not implemented, this method will call the serialize method in which the topic data representation is not considered. It is VERY IMPORTANT that the user sets the SerializedPayload length correctly.

Parameters:
  • [in] – data Pointer to the data

  • [out] – payload Pointer to the payload

  • [in] – data_representation Representation that should be used to encode the data into the payload.

Return type:

boolean

Returns:

True if correct.

set_name(*args)

Overload 1:

Set topic data type name

Parameters:

nam (string) – Topic data type name


Overload 2:

Set topic data type name

Parameters:

nam (std::string) – Topic data type name

property thisown

The membership flag

type_identifiers()

Get the type identifiers

Return type:

eprosima::fastdds::dds::xtypes::TypeIdentifierPair

Returns:

‘xtypes::TypeIdentifierPair’

21.1.5.3. TopicDescription
class fastdds.TopicDescription(*args, **kwargs)

Class TopicDescription, represents the fact that both publications and subscriptions are tied to a single data-type

get_impl()
get_name()

Get the name used to create this TopicDescription.

Return type:

string

Returns:

the name used to create this TopicDescription.

get_participant()

Get the DomainParticipant to which the TopicDescription belongs.

Return type:

DomainParticipant

Returns:

The DomainParticipant to which the TopicDescription belongs.

get_type_name()

Get the associated type name.

Return type:

string

Returns:

the type name.

property thisown

The membership flag

21.1.5.4. TopicListener
class fastdds.TopicListener

Class TopicListener, it should be used by the end user to implement specific callbacks to certain actions.

on_inconsistent_topic(topic, status)

Virtual function to be implemented by the user containing the actions to be performed when another topic exists with the same name but different characteristics.

Parameters:
  • topic (Topic) – Topic

  • status (InconsistentTopicStatus) – The inconsistent topic status

property thisown

The membership flag

21.1.5.5. TopicQos
class fastdds.TopicQos

Class TopicQos, containing all the possible Qos that can be set for a determined Topic. Although these values can be set and are transmitted during the Endpoint Discovery Protocol, not all of the behaviour associated with them has been implemented in the library. Please consult each of them to check for implementation details and default values.

deadline(*args)

Overload 1:

Getter for DeadlineQosPolicy

Return type:

DeadlineQosPolicy

Returns:

DeadlineQos reference


Overload 2:

Getter for DeadlineQosPolicy

Return type:

DeadlineQosPolicy

Returns:

DeadlineQos reference


Overload 3:

Setter for DeadlineQosPolicy

Parameters:

deadline (DeadlineQosPolicy) – new value for the DeadlineQosPolicy

destination_order(*args)

Overload 1:

Getter for DestinationOrderQosPolicy

Return type:

DestinationOrderQosPolicy

Returns:

DestinationOrderQos reference


Overload 2:

Getter for DestinationOrderQosPolicy

Return type:

DestinationOrderQosPolicy

Returns:

DestinationOrderQos reference


Overload 3:

Setter for DestinationOrderQosPolicy

Parameters:

destination_order (DestinationOrderQosPolicy) – new value for the DestinationOrderQosPolicy

durability(*args)

Overload 1:

Getter for DurabilityQosPolicy

Return type:

DurabilityQosPolicy

Returns:

DurabilityQos reference


Overload 2:

Getter for DurabilityQosPolicy

Return type:

DurabilityQosPolicy

Returns:

DurabilityQos reference


Overload 3:

Setter for DurabilityQosPolicy

Parameters:

durability (DurabilityQosPolicy) – new value for the DurabilityQosPolicy

durability_service(*args)

Overload 1:

Getter for DurabilityServiceQosPolicy

Return type:

DurabilityServiceQosPolicy

Returns:

DurabilityServiceQos reference


Overload 2:

Getter for DurabilityServiceQosPolicy

Return type:

DurabilityServiceQosPolicy

Returns:

DurabilityServiceQos reference


Overload 3:

Setter for DurabilityServiceQosPolicy

Parameters:

durability_service (DurabilityServiceQosPolicy) – new value for the DurabilityServiceQosPolicy

history(*args)

Overload 1:

Getter for HistoryQosPolicy

Return type:

HistoryQosPolicy

Returns:

HistoryQos reference


Overload 2:

Getter for HistoryQosPolicy

Return type:

HistoryQosPolicy

Returns:

HistoryQos reference


Overload 3:

Setter for HistoryQosPolicy

Parameters:

history (HistoryQosPolicy) – new value for the HistoryQosPolicy

latency_budget(*args)

Overload 1:

Getter for LatencyBudgetQosPolicy

Return type:

LatencyBudgetQosPolicy

Returns:

LatencyBudgetQos reference


Overload 2:

Getter for LatencyBudgetQosPolicy

Return type:

LatencyBudgetQosPolicy

Returns:

LatencyBudgetQos reference


Overload 3:

Setter for LatencyBudgetQosPolicy

Parameters:

latency_budget (LatencyBudgetQosPolicy) – new value for the LatencyBudgetQosPolicy

lifespan(*args)

Overload 1:

Getter for LifespanQosPolicy

Return type:

LifespanQosPolicy

Returns:

LifespanQos reference


Overload 2:

Getter for LifespanQosPolicy

Return type:

LifespanQosPolicy

Returns:

LifespanQos reference


Overload 3:

Setter for LifespanQosPolicy

Parameters:

lifespan (LifespanQosPolicy) – new value for the LifespanQosPolicy

liveliness(*args)

Overload 1:

Getter for LivelinessQosPolicy

Return type:

LivelinessQosPolicy

Returns:

LivelinessQos reference


Overload 2:

Getter for LivelinessQosPolicy

Return type:

LivelinessQosPolicy

Returns:

LivelinessQos reference


Overload 3:

Setter for LivelinessQosPolicy

Parameters:

liveliness (LivelinessQosPolicy) – new value for the LivelinessQosPolicy

ownership(*args)

Overload 1:

Getter for OwnershipQosPolicy

Return type:

OwnershipQosPolicy

Returns:

OwnershipQos reference


Overload 2:

Getter for OwnershipQosPolicy

Return type:

OwnershipQosPolicy

Returns:

OwnershipQos reference


Overload 3:

Setter for OwnershipQosPolicy

Parameters:

ownership (OwnershipQosPolicy) – new value for the OwnershipQosPolicy

reliability(*args)

Overload 1:

Getter for ReliabilityQosPolicy

Return type:

ReliabilityQosPolicy

Returns:

ReliabilityQos reference


Overload 2:

Getter for ReliabilityQosPolicy

Return type:

ReliabilityQosPolicy

Returns:

ReliabilityQos reference


Overload 3:

Setter for ReliabilityQosPolicy

Parameters:

reliability (ReliabilityQosPolicy) – new value for the ReliabilityQosPolicy

resource_limits(*args)

Overload 1:

Getter for ResourceLimitsQosPolicy

Return type:

ResourceLimitsQosPolicy

Returns:

ResourceLimitsQos reference


Overload 2:

Getter for ResourceLimitsQosPolicy

Return type:

ResourceLimitsQosPolicy

Returns:

ResourceLimitsQos reference


Overload 3:

Setter for ResourceLimitsQosPolicy

Parameters:

resource_limits (ResourceLimitsQosPolicy) – new value for the ResourceLimitsQosPolicy

property thisown

The membership flag

topic_data(*args)

Overload 1:

Getter for TopicDataQosPolicy

Return type:

TopicDataQosPolicy

Returns:

TopicDataQos reference


Overload 2:

Getter for TopicDataQosPolicy

Return type:

TopicDataQosPolicy

Returns:

TopicDataQos reference


Overload 3:

Setter for TopicDataQosPolicy

Parameters:

value (TopicDataQosPolicy) – new value for the TopicDataQosPolicy

transport_priority(*args)

Overload 1:

Getter for TransportPriorityQosPolicy

Return type:

TransportPriorityQosPolicy

Returns:

TransportPriorityQos reference


Overload 2:

Getter for TransportPriorityQosPolicy

Return type:

TransportPriorityQosPolicy

Returns:

TransportPriorityQos reference


Overload 3:

Setter for TransportPriorityQosPolicy

Parameters:

transport_priority (TransportPriorityQosPolicy) – new value for the TransportPriorityQosPolicy

fastdds.TOPIC_QOS_DEFAULT = <fastdds.TopicQos>
21.1.5.6. TypeIdV1
class fastdds.TypeIdV1(*args)

Class TypeIdV1

clear()

Clears the QosPolicy object

get()

Getter for the TypeIndentifier

Return type:

eprosima::fastdds::dds::xtypes::TypeIdentifier

Returns:

TypeIdentifier reference

property m_type_identifier

Type Identifier

property thisown

The membership flag

21.1.5.7. TypeInformation
class fastdds.TypeInformation(*args)

This class represents the structure TypeInformation defined by the user in the IDL file.

property thisown

The membership flag

21.1.5.8. TypeObjectV1
class fastdds.TypeObjectV1(*args)

Class TypeObjectV1

clear()

Clears the QosPolicy object

get()

Getter for the TypeObject

Return type:

eprosima::fastdds::dds::xtypes::TypeObject

Returns:

TypeObject reference

property m_type_object

Type Object

property thisown

The membership flag

21.1.5.9. TypeSupport
class fastdds.TypeSupport(*args)

Notes: This class inherits from std::shared_ptr<TopicDataType>. Class TypeSupport used to provide the DomainRTPSParticipant with the methods to serialize, deserialize and get the key of a specific data type. The user should created a class that inherits from this one, where Serialize and deserialize methods MUST be implemented.

calculate_serialized_size(data, data_representation)

Returns a function which can be used to calculate the serialized size of the provided data.

Parameters:
  • [in] – data Pointer to data.

  • [in] – data_representation Representation that should be used for calculating the serialized size.

Return type:

int

Returns:

Functor which calculates the serialized size of the data.

compute_key(*args)

Overload 1:

Getter for the data key

Parameters:
  • data (void) – Pointer to serialized payload containing the data.

  • i_handle (InstanceHandle_t) – InstanceHandle pointer to store the key

  • force_md5 (boolean) – boolean to force md5 (default: false)

Return type:

boolean

Returns:

true if the key is returned, false if not


Overload 2:

Getter for the data key

Parameters:
  • payload (eprosima::fastdds::rtps::SerializedPayload_t) – Pointer to data

  • i_handle (InstanceHandle_t) – InstanceHandle pointer to store the key

  • force_md5 (boolean) – boolean to force md5 (default: false)

Return type:

boolean

Returns:

true if the key is returned, false if not


Overload 3:

Getter for the data key

Parameters:
  • payload (eprosima::fastdds::rtps::SerializedPayload_t) – Pointer to data

  • i_handle (InstanceHandle_t) – InstanceHandle pointer to store the key

  • force_md5 – boolean to force md5 (default: false)

Return type:

boolean

Returns:

true if the key is returned, false if not

create_data()

Creates new data

Return type:

void

Returns:

Pointer to the data

delete_data(data)

Deletes data

Parameters:

data (void) – Pointer to the data to delete

deserialize(payload, data)

Deserializes the data

Parameters:
  • payload (eprosima::fastdds::rtps::SerializedPayload_t) – Pointer to payload

  • data (void) – Pointer to data

Return type:

boolean

Returns:

true if it is deserialized correctly, false if not

empty()

Check if the TypeSupport is empty

Return type:

boolean

Returns:

true if empty, false if not

get_type_name()

Getter for the type name

Return type:

string

Returns:

name of the data type

is_bounded()

Checks if the type is bounded.

is_plain(data_representation)

Checks if the type is plain when using a specific encoding.

register_type(*args)

Overload 1:

Registers the type on a participant

Parameters:

participant (DomainParticipant) – DomainParticipant where the type is going to be registered

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the type name is empty, RETCODE_PRECONDITION_NOT_MET if there is another type with the same name registered on the DomainParticipant and RETCODE_OK if it is registered correctly


Overload 2:

Registers the type on a participant

Parameters:
  • participant (DomainParticipant) – DomainParticipant where the type is going to be registered

  • type_name (string) – Name of the type to register

Return type:

int

Returns:

RETCODE_BAD_PARAMETER if the type name is empty, RETCODE_PRECONDITION_NOT_MET if there is another type with the same name registered on the DomainParticipant and RETCODE_OK if it is registered correctly

serialize(data, payload, data_representation)

Serializes the data

Parameters:
  • data (void) – Pointer to data

  • payload (eprosima::fastdds::rtps::SerializedPayload_t) – Pointer to payload

  • [in] – data_representation Representation that should be used to encode the data into the payload.

Return type:

boolean

Returns:

true if it is serialized correctly, false if not

set(ptr)
property thisown

The membership flag

1. Introduction

eProsima Fast DDS-Gen is a Java application that generates eProsima Fast DDS source code using the data types defined in an IDL (Interface Definition Language) file. This generated source code can be used in any Fast DDS application in order to define the data type of a topic, which will later be used to publish or subscribe. eProsima Fast DDS defines the data type exchanged in a Topic through two classes: the TypeSupport and the TopicDataType. TopicDataType describes the data type exchanged between a publication and a subscription, i.e. the data corresponding to a Topic; while TypeSupport encapsulates an instance of TopicDataType, providing the functions needed to register the type and interact with the publication and subscription. Please refer to Definition of data types for more information on data types.

To declare the structured data, the IDL format must be used. IDL is a specification language, made by OMG (Object Management Group), which describes an interface in a language independent manner, allowing communication between software components that do not share the same language. The eProsima Fast DDS-Gen tool reads the IDL files and parses a subset of the OMG IDL specification to generate source code for data serialization. This subset includes the data type descriptions included in Defining a data type via IDL. The rest of the file content is ignored.

eProsima Fast DDS-Gen generated source code uses Fast CDR, a C++11 library that provides the data serialization and codification mechanisms. Therefore, as stated in the RTPS standard, when the data are sent, they are serialized and encoded using the corresponding Common Data Representation (CDR). The CDR transfer syntax is a low-level representation for inter-agents transfer, mapping from OMG IDL data types to byte streams. Please refer to the official CDR specification for more information on the CDR transfer syntax (see PDF section 15.3).

The main feature of eProsima Fast DDS-Gen is to facilitate the implementation of DDS applications without the knowledge of serialization or deserialization mechanisms. With Fast DDS-Gen it is also possible to generate the C++ source code of a DDS application with a publisher and a subscriber that uses the eProsima Fast DDS library (see Building a publish/subscribe application). Fast DDS-Gen can also generate Python bindings for the data types in order to use them within a Python-based Fast DDS application (see Building Python auxiliary libraries).

For installing Fast DDS-Gen, please refer to Linux installation of Fast DDS-Gen or to Windows installation of Fast DDS-Gen.

2. Usage

This section explains the usage of Fast DDS-Gen tool and briefly describes the generated files.

2.1. Running the Fast DDS-Gen Java application

First, the steps outlined in Linux installation of Fast DDS-Gen or Window installation of Fast DDS-Gen must be accomplished for the installation of Fast DDS-Gen. According to this section, an executable file for Linux and Windows that runs the Java Fast DDS-Gen application is available in the scripts folder. If the scripts folder path is added to the PATH environment variable, Fast DDS-Gen can be executed running the following commands:

  • Linux:

    $ fastddsgen
    
  • Windows:

    > fastddsgen.bat
    

Note

In case the PATH has not been modified, these scripts can be found in the <fastddsgen_directory>/scripts directory.

2.2. Supported options

The expected argument list of the application is:

fastddsgen [<options>] <IDL file> [<IDL file> ...]

Where the options are:

Option

Description

-cs

Enables case sensitivity in variable names.

-d <directory>

Sets the output directory for the generated files.

-default-container-prealloc-size

Sets the default preallocated size for unbounded collections (sequences and maps)
Default value: 0 (empty collection).

-default_extensibility <extensibility>
-de <extensibility>

Sets the default extensibility for types without the @extensibility annotation.
Values:
- final
- appendable (default)
- mutable

-example <platform>

Generates an example and a solution to compile the generated source code for a specific
platform. The help command shows the supported platforms.

-extrastg <template> <output>

Specifies a custom template used for generating source code.
This option expects the location of the template and the location of the file where source code output will be stored.
A custom template example can be found in this link

-flat-output-dir

Ignores input files relative paths and place all generated files in the specified output directory.

-help

Shows the help information

-I <directory>

Adds directory to preprocessor include paths.

-no-typesupport

Avoids generating the type support files.

-no-typeobjectsupport

Avoids generating the TypeObject support specific files.
Enabled automatically if -no-typesupport argument is used.

-no-dependencies

Avoids processing the dependent IDL files.

-ppDisable

Disables the preprocessor.

-ppPath

Specifies the preprocessor path.

-python

Generates source code and a CMake solution to compile a library containing the data types
Python bindings required to run a Fast DDS Python-based application. This option is incompatible with -example.

-replace

Replaces the generated source code files even if they exist.

-t <directory>

Sets a specific directory as a temporary directory.

-typeros2

Generates type naming compatible with ROS 2.

-version

Shows the current version of eProsima Fast DDS-Gen.

Please refer to XTypes for more information on TypeObject representation.

3. Building a publish/subscribe application

Fast DDS-Gen can be used to build a fully functional publication/subscription application from an IDL file that defines the Topic under which messages are published and received. The application generated allows for the creation of as many publishers and subscribers as desired, all belonging to the same Domain and communicating using the same Topic.

3.1. Background

eProsima Fast DDS-Gen is a Java application that generates eProsima Fast DDS source code using the data types defined in an IDL (Interface Definition Language) file. This generated source code can be used in any Fast DDS application in order to define the data type of a topic, which will later be used to publish or subscribe. Please refer to Fast DDS-Gen introduction for more information.

3.2. Prerequisites

First of all, follow the steps outlined in the Installation Manual for the installation of eProsima Fast DDS and all its dependencies. Moreover, perform the steps outlined in Linux installation of Fast DDS-Gen or in Window installation of Fast DDS-Gen, depending on the operating system, for the installation of the eProsima Fast DDS-Gen tool.

3.3. Create the application workspace

The application workspace will have the following structure at the end of the project. The file build/HelloWorld is the generated Fast DDS application.

.
└── FastDDSGenHelloWorld
    ├── build
    │   ├── CMakeCache.txt
    │   ├── CMakeFiles
    │   ├── cmake_install.cmake
    │   ├── HelloWorld
    │   ├── libHelloWorld_lib.a
    │   └── Makefile
    ├── CMakeLists.txt
    ├── HelloWorld.hpp
    ├── HelloWorld.idl
    ├── HelloWorldCdrAux.hpp
    ├── HelloWorldCdrAux.ipp
    ├── HelloWorldPublisher.cxx
    ├── HelloWorldPublisher.h
    ├── HelloWorldPubSubMain.cxx
    ├── HelloWorldPubSubTypes.cxx
    ├── HelloWorldPubSubTypes.h
    ├── HelloWorldSubscriber.cxx
    ├── HelloWorldSubscriber.h
    ├── HelloWorldTypeObjecSupport.cxx
    └── HelloWorldTypeObjecSupport.h

Execute the following command to create the directory in which the files generated by Fast DDS-Gen will be saved.

mkdir FastDDSGenHelloWorld && cd FastDDSGenHelloWorld
mkdir build

3.4. Import linked libraries and its dependencies

The DDS application requires the Fast DDS and Fast CDR libraries. The way of making these accessible from the workspace depends on the installation procedure followed in the Installation Manual.

3.4.1. Installation from binaries

If the installation from binaries has been followed, these libraries are already accessible from the workspace.

  • On Linux: The header files can be found in directories /usr/include/fastdds/ and /usr/include/fastcdr/ for Fast DDS and Fast CDR respectively. The compiled libraries of both can be found in the directory /usr/lib/.

  • On Windows: The header files can be found in directories C:\Program Files\eProsima\fastdds <major>.<minor>.<patch>\include\fastdds and C:\Program Files\eProsima\fastdds <major>.<minor>.<patch>\include\fastcdr\ for Fast DDS and Fast CDR respectively. The compiled libraries of both can be found in the directory C:\Program Files\eProsima\fastdds <major>.<minor>.<patch>\lib\.

3.4.2. Colcon installation

If the Colcon installation has been followed, there are several ways to import the libraries. To make these accessible only from the current shell session, run one of the following two commands.

  • On Linux:

source <path/to/Fast-DDS/workspace>/install/setup.bash
  • On Windows:

<path/to/Fast-DDS/workspace>/install/setup.bat

However, to make these accessible from any session, add the Fast DDS installation directory to the $PATH variable in the shell configuration files running the following command.

  • On Linux:

echo 'source <path/to/Fast-DDS/workspace>/install/setup.bash' >> ~/.bashrc
  • On Windows: Open the Edit the system environment variables control panel and add <path/to/Fast-DDS/workspace>/install/setup.bat to the PATH.

3.5. Creating the IDL file with the data type

To build a minimal application, the Topic must be defined by means of an IDL file. For this example the Topic data type defined by IDL is just a string message. Topics are explained in more detail in Topic, while the Topic data types to be defined using IDL are presented in Definition of data types. In the preferred text editor, create the HelloWorld.idl file with the following content and save it in the FastDDSGenHelloWorld directory.

// HelloWorld.idl
struct HelloWorld
{
    string message;
};

Then, this file is translated to something Fast DDS understands. For this, use the Fast DDS-Gen code generation tool, which can do two different things:

  1. Generate C++ definitions for a custom topic.

  2. Generate a functional example that uses the topic data.

The second option is the one used to create this publish/subscribe application, while the first option is applied in this other tutorial: Writing a simple C++ publisher and subscriber application.

3.6. Generating a minimal functional example

If the steps outlined in the Installation Manual have been followed, then Fast DDS, Fast CDR, and Fast-RTPS-Gen should be installed in the system.

3.6.1. Generate the Fast DDS source code

The application files are generated using the following command. The -example option creates an example application, and the CMake files needed to build it. In the workspace directory (FastDDSGenHelloWorld directory), execute one of the following commands according to the installation followed and the operating system.

  • On Linux:

    • For an installation from binaries or a colcon installation:

    <path-to-Fast-DDS-workspace>/src/fastddsgen/scripts/fastddsgen -example CMake HelloWorld.idl
    
    • For a stand-alone installation, run:

    <path-to-Fast-DDS-Gen>/scripts/fastddsgen -example CMake HelloWorld.idl
    
  • On Windows:

    • For a colcon installation:

    <path-to-Fast-DDS-workspace>/src/fastddsgen/scripts/fastddsgen.bat -example CMake HelloWorld.idl
    
    • For a stand-alone installation, run:

    <path-to-Fast-DDS-Gen>/scripts/fastddsgen.bat -example CMake HelloWorld.idl
    
    • For an installation from binaries, run:

    fastddsgen.bat -example CMake HelloWorld.idl
    

Warning

The colcon installation does not build the fastddsgen.jar file although it does download the Fast DDS-Gen repository. The following commands must be executed to build the Java executable:

cd <path-to-Fast-DDS-workspace>/src/fastddsgen
gradle assemble

3.6.2. Build the Fast DDS application

Then, compile the generated code executing the following commands from the FastDDSGenHelloWorld directory.

  • On Linux:

cd build
cmake ..
make
  • On Windows:

cd build
cmake -G "Visual Studio 15 2017 Win64" ..
cmake --build .

3.6.3. Run the Fast DDS application

The application build can be used to spawn any number of publishers and subscribers associated with the topic.

  • On Linux:

./HelloWorld publisher
./HelloWorld subscriber
  • On Windows:

HelloWorld.exe publisher
HelloWorld.exe subscriber

Each time <Enter> is pressed on the Publisher, a new datagram is generated, sent over the network and received by Subscribers currently online. If more than one subscriber is available, it can be seen that the message is equally received on all listening nodes.

The values on the custom IDL-generated data type can also be modified as indicated below.

HelloWorld sample;     //Auto-generated container class for topic data from Fast DDS-Gen
sample.msg("Hello there!");     // Add contents to the message
data_writer->write(&sample);     //Publish

Warning

It may be necessary to set up a special rule in the Firewall for eprosima Fast DDS to work correctly on Windows.

3.7. Summary and next steps

In this tutorial, a publisher/subscriber DDS application using Fast DDS-Gen has been built. The tutorial also describes how to generate IDL files that contain the description of the Topic data type.

To continue developing DDS applications please take a look at the eProsima Fast DDS examples on github for ideas on how to improve this basic application through different configuration options, and also for examples of advanced Fast DDS features.

4. Building Python auxiliary libraries

eProsima Fast DDS-Gen can generate the required source files and CMake project to build the Python modules that allow the use of the IDL defined data types within a Fast DDS Python-based application. Each IDL file will result in a new Python module that will contain all the data types defined in the file. The Python binding is generated building the provided solution using SWIG.

Calling eProsima Fast DDS-Gen with the option -python will generate these files. eProsima Fast DDS-Gen will generate a .i file which will be processed by SWIG and a CMake project to call SWIG first generating C++ files (for connecting C++ and Python) and Python files (Python module for your type) and then compiling the C++ sources.

Note

The Python bindings does not support the use of namespaces.

Before calling CMake, the Building process needs several Dependencies to be met.

4.1. Dependencies

4.1.1. SWIG

SWIG is a development tool that allows connecting programs written in C/C++ with a variety of other programming languages, among them Python. SWIG version lower than 4.2 is required to build Fast DDS Python bindings.

Note

More recent SWIG releases are not yet supported. Please, ensure to be using SWIG 4.0.

SWIG can be installed directly from the package manager of the appropriate Linux distribution. For Ubuntu, please run:

sudo apt install swig

Warning

For Ubuntu 24.04, SWIG must be installed using the following command:

sudo apt install swig4.1

4.1.2. Header files and static library for Python

Python static libraries and header files are needed to compile C++ source code generated by SWIG. They can be installed directly from the package manager of the appropriate Linux distribution. For Ubuntu, please run:

sudo apt install libpython3-dev

4.2. Building

Call CMake:

mkdir build
cd build
cmake ..
cmake --build .

This will create the Python files (.py) with the modules (one per each IDL file) that have to be imported within the Python script.

Note

The python bindings does not support using different modules in the same idl file. Split them in different files for expected behavior.

5. Defining a data type via IDL

This section describes the data types that can be defined using IDL files, as well as other mechanisms for building data types using IDL files.

5.1. Supported IDL types

Be aware that Fast DDS-Gen is not case sensitive as it is specified in the IDL specification. To activate case sensitivity use option -cs when running Fast DDS-Gen (see Supported options).

Warning

Note that IDL files created by ROS 2 are not necessarily compatible with Fast DDS applications, since they are processed in a different manner and can lead to incompatible type definitions. For a detailed explanation on how to ensure compatibility between ROS 2 and Fast DDS applications, please refer to this Vulcanexus tutorial.

5.1.1. Primitive types

The following table shows the basic IDL types supported by Fast DDS-Gen and how they are mapped to C++11.

IDL

C++11

char

char

octet

uint8_t

short

int16_t

unsigned short

uint16_t

long

int32_t

unsigned long

uint32_t

long long

int64_t

unsigned long long

uint64_t

float

float

double

double

long double

long double

boolean

bool

string

std::string

5.1.2. Arrays

Fast DDS-Gen supports unidimensional and multidimensional arrays. Arrays are always mapped to std::array containers. The following table shows the array types supported and their mapping.

IDL

C++11

char a[5]

std::array<char,5> a

octet a[5]

std::array<uint8_t,5> a

short a[5]

std::array<int16_t,5> a

unsigned short a[5]

std::array<uint16_t,5> a

long a[5]

std::array<int32_t,5> a

unsigned long a[5]

std::array<uint32_t,5> a

long long a[5]

std::array<int64_t,5> a

unsigned long long a[5]

std::array<uint64_t,5> a

float a[5]

std::array<float,5> a

double a[5]

std::array<double,5> a

5.1.3. Sequences

Fast DDS-Gen supports sequences, which map into the std::vector container. The following table represents how the map between IDL and C++11 is handled.

IDL

C++11

sequence<char>

std::vector<char>

sequence<octet>

std::vector<uint8_t>

sequence<short>

std::vector<int16_t>

sequence<unsigned short>

std::vector<uint16_t>

sequence<long>

std::vector<int32_t>

sequence<unsigned long>

std::vector<uint32_t>

sequence<long long>

std::vector<int64_t>

sequence<unsigned long long>

std::vector<uint64_t>

sequence<float>

std::vector<float>

sequence<double>

std::vector<double>

5.1.4. Maps

Fast DDS-Gen supports maps, which are equivalent to the std::map container. The equivalence between types is handled in the same way as for sequences.

IDL

C++11

map<char, unsigned long long>

std::map<char, uint64_T>

Note

Only Primitive types are currently supported.

5.1.5. Structures

You can define an IDL structure with a set of members with multiple types. It will be converted into a C++ class in which the members of the structure defined via IDL are mapped to private data members of the class. Furthermore, set() and get() member functions are created to access these private data members.

The following IDL structure:

struct Structure
{
    octet octet_value;
    long long_value;
    string string_value;
};

Would be converted to:

class Structure
{
public:

    Structure();
    ~Structure();
    Structure(
            const Structure& x);
    Structure(
            Structure&& x);
    Structure& operator =(
            const Structure& x);
    Structure& operator =(
            Structure&& x);

    void octet_value(
            uint8_t _octet_value);
    uint8_t octet_value() const;
    uint8_t& octet_value();
    void long_value(
            int64_t _long_value);
    int64_t long_value() const;
    int64_t& long_value();
    void string_value(
            const std::string
            & _string_value);
    void string_value(
            std::string&& _string_value);
    const std::string& string_value() const;
    std::string& string_value();

private:

    uint8_t m_octet_value;
    int64_t m_long_value;
    std::string m_string_value;
};

Structures can inherit from other structures, extending their member set.

struct ParentStruct
{
    octet parent_member;
};

struct ChildStruct : ParentStruct
{
    long child_member;
};

In this case, the resulting C++ code will be:

class ParentStruct
{
    octet parent_member;
};

class ChildStruct : public ParentStruct
{
    long child_member;
};
5.1.5.1. Optional members

A member of a structure can be optional. This is achieved by writing the @optional annotation before the member.

struct StructWithOptionalMember
{
    @optional octet octet_opt;
};

An optional member is converted into a template class eprosima::fastcdr::optional<T>, where T is the member’s type.

class StructWithOptionalMember
{
    eprosima::fastcdr::optional<octet> octet_opt;
};

Before reading the value of the optional member, it should be checked the optional contains a value using has_value() function. Accessing a null optional throws a eprosima::fastcdr::exception::BadOptionalAccessException exception.

if (octet_opt.has_value())
{
    octet oc = octet_opt.value();
}
5.1.5.2. Extensibility

In order to support evolving types without breaking interoperability, the concept of type extensibility is supported by Fast DDS-Gen. There are three extensibility kinds: final, appendable and mutable.

  • FINAL extensibility indicates that the type is strictly defined. It is not possible to add members while maintaining type assignability.

  • APPENDABLE extensibility indicates that two types, where one contains all of the members of the other plus additional members appended to the end, may remain assignable.

  • MUTABLE extensibility indicates that two types may differ from one another in the additional, removal, and/or transposition of members while remaining assignable.

@extensibility(FINAL)
struct FinalStruct
{
    octet octet_opt;
};

@extensibility(APPENDABLE)
struct AppendableStruct
{
    octet octet_opt;
};

@extensibility(MUTABLE)
struct MutableStruct
{
    octet octet_opt;
};

Note

XCDRv1 encoding algorithm is not able to manage correctly the deserialization of an appendable structure when it is used as a member of another one.

5.1.6. Unions

In IDL, a union is defined as a sequence of members with their own types and a discriminant that specifies which member is in use. An IDL union type is mapped as a C++ class with member functions to access the union members and the discriminant.

The following IDL union:

union Union switch(long)
{
   case 1:
    octet octet_value;
  case 2:
    long long_value;
  case 3:
    string string_value;
};

Would be converted to:

class Union
{
public:

    Union();
    ~Union();
    Union(
            const Union& x);
    Union(
            Union&& x);
    Union& operator =(
            const Union& x);
    Union& operator =(
            Union&& x);

    void d(
            int32_t __d);
    int32_t _d() const;
    int32_t& _d();

    void octet_value(
            uint8_t _octet_value);
    uint8_t octet_value() const;
    uint8_t& octet_value();
    void long_value(
            int64_t _long_value);
    int64_t long_value() const;
    int64_t& long_value();
    void string_value(
            const std::string
            & _string_value);
    void string_value(
            std:: string&& _string_value);
    const std::string& string_value() const;
    std::string& string_value();

private:

    int32_t m__d;
    uint8_t m_octet_value;
    int64_t m_long_value;
    std::string m_string_value;
};

5.1.7. Bitsets

Bitsets are a special kind of structure, which encloses a set of bits. A bitset can represent up to 64 bits. Each member is defined as bitfield and eases the access to a part of the bitset.

For example:

bitset MyBitset
{
    bitfield<3> a;
    bitfield<10> b;
    bitfield<12, long> c;
};

The type MyBitset will store a total of 25 bits (3 + 10 + 12) and will require 32 bits in memory (lowest primitive type to store the bitset’s size).

  • The bitfield ‘a’ allows us to access to the first 3 bits (0..2).

  • The bitfield ‘b’ allows us to access to the next 10 bits (3..12).

  • The bitfield ‘c’ allows us to access to the next 12 bits (13..24).

The resulting C++ code will be similar to:

class MyBitset
{
public:

    void a(
            char _a);
    char a() const;

    void b(
            uint16_t _b);
    uint16_t b() const;

    void c(
            int32_t _c);
    int32_t c() const;

private:

    std::bitset<25> m_bitset;
};

Internally, it is stored as a std::bitset. For each bitfield, get() and set() member functions are generated with the smaller possible primitive unsigned type to access it. In the case of bitfield ‘c’, the user has established that this accessing type will be long, so the generated code uses int32_t instead of automatically use uint16_t.

Bitsets can inherit from other bitsets, extending their member set.

bitset ParentBitset
{
    bitfield<3> parent_member;
};

bitset ChildBitset : ParentBitset
{
    bitfield<10> child_member;
};

In this case, the resulting C++ code will be:

class ParentBitset
{
    std::bitset<3> parent_member;
};

class ChildBitset : public ParentBitset
{
    std::bitset<10> child_member;
};

Note that in this case, ChildBitset will have two std::bitset data members, one belonging to ParentBitset and the other belonging to ChildBitset.

5.1.8. Enumerations

An enumeration in IDL format is a collection of identifiers that have an associated numeric value. An IDL enumeration type is mapped directly to the corresponding C++11 enumeration definition.

The following IDL enumeration:

enum Enumeration
{
    RED,
    GREEN,
    @value(3)
    BLUE
};

Would be converted to:

enum Enumeration : int32_t
{
    RED,
    GREEN,
    BLUE = 3
};

5.1.9. Bitmasks

Bitmasks are a special kind of Enumeration to manage masks of bits. It allows defining bit masks based on their position.

The following IDL bitmask:

@bit_bound(8)
bitmask MyBitMask
{
    @position(0) flag0,
    @position(1) flag1,
    @position(4) flag4,
    @position(6) flag6,
    flag7
};

Would be converted to:

enum MyBitMask : uint8_t
{
    flag0 = 0x01 << 0,
    flag1 = 0x01 << 1,
    flag4 = 0x01 << 4,
    flag6 = 0x01 << 6,
    flag7 = 0x01 << 7
};

The annotation bit_bound defines the width of the associated enumeration. It must be a positive number between 1 and 64. If omitted, it will be 32 bits. For each flag, the user can use the annotation position to define the position of the flag. If omitted, it will be auto incremented from the last defined flag, starting at 0.

5.1.10. Modules

In order to avoid collision between variable names, modules can be defined within the IDL file. A module would be converted into a namespace in C++.

5.1.11. Data types with a key

In order to use keyed topics, the user should define some key members inside the structure. This is achieved by writing the @key annotation before the members of the structure that are used as keys. For example in the following IDL file the id and type field would be the keys:

struct MyType
{
    @key long id;
    @key string type;
    long positionX;
    long positionY;
};

Fast DDS-Gen automatically detects these tags and correctly generates the serialization methods for the key generation function in TopicDataType (getKey()). This function will obtain the 128-bit MD5 digest of the big-endian serialization of the Key Members.

5.2. Including other IDL files

Other IDL files can be included in addition to the current IDL file. Fast DDS-Gen uses a C/C++ preprocessor for this purpose, and #include directive can be used to include an IDL file. Preprocessor directives guarding against multiple inclusion of the same IDL file are also advisable.

 #include "OtherFile.idl"
 #include <AnotherFile.idl>

If Fast DDS-Gen does not find a C/C++ preprocessor in default system paths, the preprocessor path can be specified using parameter -ppPath. The parameter -ppDisable can be used to disable the usage of the C/C++ preprocessor.

5.3. Annotations

The application allows the user to define and use their own annotations as defined in the OMG IDL specification.

@annotation MyAnnotation
{
    long value;
    string name;
};

Additionally, the following standard annotations are defined by the specification and considered builtin (these annotations might be applied without the need of defining them).

Builtin Annotation

Behavior

Supported

@ami

Asynchronous interface or operation.

@appendable

Shortcut for @extensibility(APPENDABLE).

@autoid

Member ID algorithm configuration if there is no member ID explicitly set using @id annotation.
Possible values are SEQUENTIAL (member ID is assigned sequentially. Default value) or
HASH (member ID is calculated with an algorithm involving hashing the member name).
This annotation might be defined in module, structure or union declarations.

@bit_bound

Set number of bits on bitmasks and enumerations underlying primitive type.
Currently, @bit_bound can only be applied to bitmask types.

✅❌

@data_representation

Specify the DataRepresentationId required for a specific type.

@default

Set constant default value to a member.

@default_literal

Mark an enumerations literal as default.

@default_nested

Use in module declaration to mark as @nested every element defined within the module.

@extensibility

Applicable to any constructed element. Specify how the element is allowed to evolve.
Please, refer to Extensibility for more information.

@external

Member is stored in external storage.

@final

Shortcut for @extensibility(FINAL)

@hashid

Calculate the member ID with the string provided or, if empty, with the member name.

@id

Assign member ID to a structure or union member.

@ignore_literal_names

When checking evolved type compatibility, take or not into account member names.

@key

Mark a structure member as part of the key. @Key is also supported.
Please, refer to Topics, keys and instances for more information.

@max

Set a maximum constant value to the member.

@min

Set a minimum constant value to the member.

@must_understand

Mark a structure member as essential for the structure cohesion.

@mutable

Shortcut for @extensibility(MUTABLE)

@nested

Type is always used within another one.

@non_serialized

Omit member during serialization.

@oneway

One-way operation, flowing the information only on one direction.

@optional

Configure a structure member as optional. Please refer to Optional Members for more information.

@position

Set a bitflag position in bitmasks.

@range

Set a range of allowed values for the member.

@service

Interface is to be treated as a service.

@topic

Structure or union is meant to be used as Topic Data Type.

@try_construct

When checking evolved type compatibility, configure the behavior for
collection/aggregated types construction and what to do in case of failure.

@unit

Specify a unit of measurement for the member.

@value

Set constant value to enumerations literal.

@verbatim

Add comment or text to the element.

5.4. Forward declaration

Fast DDS-Gen supports forward declarations. This allows declaring inter-dependant structures, unions, etc.

struct ForwardStruct;

union ForwardUnion;

struct ForwardStruct
{
    ForwardUnion fw_union;
};

union ForwardUnion switch (long)
{
    case 0:
        ForwardStruct fw_struct;
    default:
        string empty;
};

5.5. IDL 4.2 aliases

IDL 4.2 allows using the following names for primitive types:

  • int8

  • uint8

  • int16

  • uint16

  • int32

  • uint32

  • int64

  • uint64

5.6. IDL 4.2 comments

There are two ways to write IDL comments:

  • The characters /* start a comment, which terminates with the characters */.

  • The characters // start a comment, which terminates at the end of the line on which they occur.

Please refer to the IDL 4.2 specification (Section 7.2 Lexical Conventions) for more information on IDL conventions.

/* MyStruct definition */
struct MyStruc
{
    string mymessage;   // mymessage data member.
};

1. CLI

The Fast DDS command line interface provides a set commands and sub-commands to perform, Fast DDS related, maintenance and configuration tasks.

An executable file for Linux and Windows that runs the Fast DDS CLI application is available in the tools folder. If the tools/fastdds folder path is added to the PATH, or by sourcing the <path/to/fastdds>/install/setup.bash configuration file, Fast DDS CLI can be executed running the following commands:

  • Linux:

    $ fastdds <command> [<command-args>]
    
  • Windows:

    > fastdds.bat <command> [<command-args>]
    

There are three verbs whose functionality is described in the following table:

Verbs

Description

discovery

Launches a server for Discovery Server.

shm

Allows manual cleaning of garbage files that may be generated by Shared Memory Transport

xml

Checks if a xml profile is well formed.

1.1. discovery

This command provides a simple and direct way to launch a Fast DDS Discovery Server. It encompasses two main functionalities:

  • Discovery Server CLI Easy Mode: It launches a background daemon which will automatically handle the creation of servers. The port of each server is calculated based on the Domain ID (-d argument or ROS_DOMAIN_ID), which is the only parameter that the user must specify. If no Domain ID is provided, the default value is 0.

    It is intended to be used along with the ROS2_EASY_MODE environment variable, which will manage clients connections automatically. This CLI feature allows the user to dynamically manage servers from the network: launching, stopping, restarting and even modifying their remote servers connections. For further information about this mode refer to Discovery Server Easy Mode.

  • Discovery Server CLI Standard Mode: It launches a server running in foreground with the specified parameters. Configurable parameters include IP address, port, transport protocol, XML profile, etc. In this mode, clients must know how to reach the server, which is accomplished by specifying an IP address, a port and a transport protocol like UDP or TCP. Servers do not need any prior knowledge of their clients, but require the listening IP address and port where they may be reached.

1.1.1. Discovery Server CLI Easy Mode

This mode aims to simplify the deployment and configuration of Fast DDS Discovery Servers by automatically handling the server’s connections. This mode of the CLI is meant to be used along with the ROS2_EASY_MODE environment variable, which can be used to remove multicast announcements from DDS entities and interconnect different hosts by just using the environment variable ROS2_EASY_MODE=<ip>. (Check Discovery Server Easy Mode to see a detailed explanation of this feature).

In this way, the CLI provides an auxiliary tool to obtain more advanced configuration for specific cases of use. It can be used to manage running servers, modifying their remote connections, restarting them or stopping them. Fast DDS Discovery servers are handled and monitored from a background daemon which is automatically spawned when required.

Configuration of servers launched with ROS2_EASY_MODE is available by using the following command:

fastdds discovery <command> [optional -d <domain>] [optional "<remote_server_list>"]

The following table lists the available commands for the Fast DDS Discovery Server CLI:

Command

Description

start

Start the Discovery Server daemon with the remote connections specified.
(Example: start -d 1 10.0.0.1:1).

stop

Stop the Discovery Server daemon if it is executed with no arguments. If a domain is
specified with the -d argument it will only stop the corresponding server and
the daemon will remain alive.

add

Add new remote Discovery Servers to the local server. This will connect both servers
and their sub-networks without modifying existing remote servers.

set

Rewrite the remote Discovery Servers connected to the local server. This will replace
existing remote servers with the new connections.

list

List local active Discovery Servers created with the CLI Tool or the ROS2_EASY_MODE=<ip>.

Option parameters

Description

-d  --domain

Selects the domain of the server to target for this action. It is mandatory for
commands start, add and set.

<remote_server>

It is an IP-domain pair defining a remote server to connect to:
<IP:domain>. It is mandatory with the start, add and set commands.
Only valid IPv4 addresses are accepted.

Note

The command add also accepts a remote server list using the structure "<IP:domain>;<IP:domain>;...".

1.1.1.1. Examples
  1. Start a DS in the default domain 0 pointing to itself (no remote server):

    fastdds discovery start -d 0 127.0.0.1:0
    
  2. Stop all running DS and shut down Fast DDS daemon:

    fastdds discovery stop
    
  3. Stop DS running in domain 0:

    fastdds discovery stop -d 0
    
  4. Start a DS in domain 4 pointing to remote DS in domain 4 and IP 10.0.0.7:

    fastdds discovery start -d 4 10.0.0.7:4
    
  5. Add a new remote server to DS running in domain 4 :

    fastdds discovery add -d 4 10.0.0.7:4
    
  6. List all servers running locally:

    fastdds discovery list
    
  7. Starts a DS in domain 3 pointing to local DS in domain 6:

    fastdds discovery start -d 3 127.0.0.1:6
    

1.1.2. Discovery Server CLI Standard Mode

This mode allows the user to deeply customize Discovery Servers initialization avoiding programming. However, it requires manual configuration for clients to reach the server, as they must know the server’s IP address, port and protocol. For more information on the different Fast DDS discovery mechanisms and how to configure them, please refer to Discovery.

To use this mode, execute on a shell:

fastdds discovery [optional parameters]

The following table lists the available parameters for the Fast DDS Discovery Server CLI mode:

Option

Description

-h  --help

Produce help message with examples.

-l  --udp-address

IPv4/IPv6 address chosen to listen the clients using UDP transport. Defaults to any
(0.0.0.0/::0). Instead of an address, a DNS domain name can be specified.

-p  --udp-port

UDP port chosen to listen the clients. Defaults to ‘11811’. Only one server can be
configured using the default UDP port.

-t  --tcp-address

IPv4/IPv6 address chosen to listen the clients using TCP transport. Instead of an
address, a DNS domain name can be specified. Defaults to any (0.0.0.0).

-q  --tcp-port

TCP port chosen to listen the clients. Defaults to ‘42100’. Only one server can be
configured using the default TCP port.

-b  --backup

Creates a BACKUP server (see Discovery Protocol)

-x  --xml-file

XML configuration file (see XML profiles). In this case, the default
configuration file is not loaded. The CLI options override XML configuration for
that specific parameter. The default profile in the XML file is loaded except if
a specific profile name is specified: profile_name@xml_file

-i  --server-id

Unique server identifier. Its functionality its deprecated. It can be used to select
a fixed GUID in the form shown below. Must be an integer in range [0, 255].

Executing the command without parameters will launch a server with default UDP values.

The output is:

#### Server started ####
  GUID prefix: <Default>|44.53.<server-id-in-hex>.5f.45.50.52.4f.53.49.4d.41
  Running on:  UDPv4:[<ip-address>]:<port>
               UDPv6:[<ip-address>]:<port>
               TCPv4:[<ip-address>]:<physical-port>-<logical-port>
               TCPv6:[<ip-address>]:<physical-port>-<logical-port>

Once the server is instantiated, the clients can be configured either programmatically or by XML (see Discovery Server Settings), or using environment variable ROS_DISCOVERY_SERVER (see ROS_DISCOVERY_SERVER)

Important

It is possible to interconnect servers (or backup servers) instantiated with Discovery Server CLI Standard Mode using environment variable ROS_DISCOVERY_SERVER (see ROS_DISCOVERY_SERVER) or a XML configuration file.

Note

The Security configuration of the discovery server should be done through XML. See example below.

1.1.2.1. Examples
  1. Launch a default server listening on all available interfaces on UDP port ‘11811’. Only one server can use default values per machine.

    fastdds discovery
    

    Output:

    #### Server started ####
      GUID prefix: <Default GUID>
      Running on:  UDPv4:[0.0.0.0]:11811
    
  2. Launch a default server listening on localhost with UDP port 14520. Only localhost clients can reach the server defining as ROS_DISCOVERY_SERVER=127.0.0.1:14520.

    fastdds discovery -l 127.0.0.1 -p 14520
    

    Output:

    #### Server started ####
      GUID prefix: <Default GUID>
      Running on:  UDPv4:[127.0.0.1]:14520
    

    This same output can be obtained loading the following XML configuration file DiscoveryServerCLI.xml:

    <participant profile_name="participant_profile_discovery_server_cli" is_default_profile="true">
        <rtps>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>localhost</address>
                            <port>14520</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
    
    <participant profile_name="second_participant_profile_discovery_server_cli">
        <rtps>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>192.168.36.34</address>
                            <port>8783</port>
                        </udpv4>
                    </locator>
                    <locator>
                        <udpv4>
                            <address>172.20.96.1</address>
                            <port>51083</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
        </rtps>
    </participant>
    
    <participant profile_name="secure_discovery_server_cli">
        <rtps>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>0.0.0.0</address>
                            <port>11811</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>
            <propertiesPolicy>
                <properties>
                    <!-- Activate Auth:PKI-DH plugin -->
                    <property>
                        <name>dds.sec.auth.plugin</name>
                        <value>builtin.PKI-DH</value>
                    </property>
    
                    <!-- Configure Auth:PKI-DH plugin -->
                    <property>
                        <name>dds.sec.auth.builtin.PKI-DH.identity_ca</name>
                        <value>file://maincacert.pem</value>
                    </property>
                    <property>
                        <name>dds.sec.auth.builtin.PKI-DH.identity_certificate</name>
                        <value>file://appcert.pem</value>
                    </property>
                    <property>
                        <name>dds.sec.auth.builtin.PKI-DH.private_key</name>
                        <value>file://appkey.pem</value>
                    </property>
    
                    <!-- Activate Access:Permissions plugin -->
                    <property>
                        <name>dds.sec.access.plugin</name>
                        <value>builtin.Access-Permissions</value>
                    </property>
    
                    <!-- Configure Access:Permissions plugin -->
                    <property>
                        <name>dds.sec.access.builtin.Access-Permissions.permissions_ca</name>
                        <value>file://maincacet.pem</value>
                    </property>
                    <property>
                        <name>dds.sec.access.builtin.Access-Permissions.governance</name>
                        <value>file://governance.smime</value>
                    </property>
                    <property>
                        <name>dds.sec.access.builtin.Access-Permissions.permissions</name>
                        <value>file://permissions.smime</value>
                    </property>
    
                    <!-- Activate Crypto:AES-GCM-GMAC plugin -->
                    <property>
                        <name>dds.sec.crypto.plugin</name>
                        <value>builtin.AES-GCM-GMAC</value>
                    </property>
                </properties>
            </propertiesPolicy>
        </rtps>
    </participant>
    
    fastdds discovery -x [PATH_TO_FILE]/DiscoveryServerCLI.xml
    
  3. Launch a default server listening on all available interfaces on TCP port ‘42100’. Only one server can use default values per machine.

    fastdds discovery -t
    

    Output:

    #### Server started ####
      GUID prefix: <Default GUID>
      Running on:  TCPv4:[0.0.0.0]:42100
    
  1. Launch a default server with GUID corresponding to id 1 (see Deprecated_CLI) listening on IPv6 address 2a02:ec80:600:ed1a::3 with UDP port 14520.

    fastdds discovery -i 1 -l 2a02:ec80:600:ed1a::3 -p 14520
    

    Output:

    #### Server started ####
      GUID prefix: 44.53.01.5f.45.50.52.4f.53.49.4d.41
      Running on:  UDPv6:[2a02:ec80:600:ed1a::3]:14520
    
  2. Launch a default server listening on WiFi (192.168.36.34) and Ethernet (172.20.96.1) local interfaces with UDP ports 8783 and 51083 respectively (addresses and ports are made up for the example).

    fastdds discovery -l 192.168.36.34 -p 8783 -l 172.20.96.1 -p 51083
    

    Output:

    #### Server started ####
      GUID prefix: <Default GUID>
      Running on:  UDPv4:[192.168.36.34]:8783
                   UDPv4:[172.20.96.1]:51083
    

    Using the same XML configuration file from the second example, the same output can be obtained loading a specific profile: second_participant_profile_discovery_server_cli.

    fastdds discovery -x second_participant_profile_discovery_server_cli@[PATH_TO_FILE]/DiscoveryServerCLI.xml
    
  3. Launch a default server listening on 172.30.144.1 with UDP port 12345 and provided with a backup file. If the server crashes it will automatically restore its previous state when re-enacted.

    fastdds discovery -l 172.30.144.1 -p 12345 -b
    

    Output:

    #### Backup Server started ####
      GUID prefix: <Default GUID>
      Running on:  UDPv4:[172.30.144.1]:12345
    
  4. Launch a secure server listening on all available interfaces on UDP port ‘11811’.

    fastdds discovery -x secure_discovery_server_cli@[PATH_TO_FILE]/DiscoveryServerCLI.xml
    

    Output:

    #### Server started ####
      GUID prefix: <Default GUID>
      Running on:  UDPv4:[0.0.0.0]:11811
    
  5. Launch a server reading specific profile_name configuration from XML file.

    fastdds discovery -x profile_name@[PATH_TO_FILE]/config.xml
    

    Output:

    #### Server started ####
      GUID prefix: <Default GUID>
      Running on:  UDPv4:[127.0.0.1]:56542
    
  6. Launch a server listening on localhost on default TCP port ‘42100’.

    fastdds discovery -t 127.0.0.1
    

    Output:

    #### Server started ####
      GUID prefix: <Default GUID>
      Running on:  TCPv4:[127.0.0.1]:42100-42100
    
  7. Launch a server listening on localhost and WiFi (192.163.6.34). Two TCP ports need to be specified because transports cannot share ports.

    fastdds discovery -t 127.0.0.1 -q 42100 -t 192.163.6.34 -q 42101
    

    Output:

    #### Server started ####
      GUID prefix: <Default GUID>
      Running on:  TCPv4:[127.0.0.1]:42100-42100
                   TCPv4:[192.163.6.34]:42101-42101
    

Note

When using Discovery Server over TCP, the first port shown in the output refers to the TCP Physical port and the second one to the TCP Logical port (see TCP Transport).

Note

A server can be instantiated just by passing the port arguments -p and -q. Fast DDS CLI will use the default values of the IP addresses, that is, 0.0.0.0 for both UDP and TCP.

1.2. shm

Provides maintenance tasks related with Shared Memory Transport. Shared Memory transport creates Segments, blocks of memory accessible from different processes. Zombie files are memory blocks that were reserved by shared memory and are no longer in use which take up valuable memory resources. This tool finds and frees those memory allocations.

It is also possible to clean Data Sharing segments when the --force option is used. However, this option should be used with caution, as it will remove all Data Sharing segments, including the ones that are being used by active applications.

fastdds shm [<shm-command>]

Sub-command

Description

clean

Cleans SHM zombie files.

Option

Description

-h  --help

Produce help message.

-f  --force

Force the deletion of data sharing segments.

Warning

Running this command with the --force option will remove all Data Sharing segments, including the ones that are being used by active applications. Use this option only when there are no running Fast DDS applications, as it might raise errors if the segments are still in use.

1.3. xml

Checks if a given xml profile is well formed, by matching it against a XSD schema. If the given input to the command is a path to a folder instead of a path to a file,all xml files contained in the folder will be validated.

This validation consists in checking the lack of parameters, values bounds, expected values data types and main profile structure. For further information see Creating an XML profiles file.

fastdds xml [<xml-command>]

Sub-command

Description

validate

Checks a xml profile by matching it against a XSD schema.

Option

Description

-h  --help

Produce help message.

-d  --debug

Print debug information (disabled by default)

-x  --xsd_file

XSD schema for validation (not required, Fast DDS schema is used by default)

Example

fastdds xml validate my_profile.xml

1. Docker Images

eProsima provides the Fast DDS and the Fast DDS Suite Docker images for those who want a quick demonstration of Fast DDS running on an Ubuntu platform. They can be downloaded from eProsima’s downloads page.

This Docker images were built for Ubuntu 22.04 (Jammy Jellyfish).

To run a container you need Docker installed. From a terminal, run:

sudo apt install docker.io

1.1. Leveraging Fast DDS SHM in Docker deployments

By default, Fast DDS enables both a Shared Memory Transport and Data-sharing delivery (when the configuration allows it, see Constraints). The way Fast DDS utilizes to find out whether a remote DomainParticipant is running on the same host as the local one is through a hashing of the network interfaces, which entails that two Docker container which are not sharing the same network stack will be detected as two different hosts, and therefore Fast DDS will defer to communicating through the UDP Transport instead.

To enable the use of both the Shared Memory Transport and Data-sharing in Docker deployments, two additional options need to be passed to the docker run command, those are:

  • –network=host: This option shares the host’s network stack with the containers, and therefore Fast DDS will be able to identify them as the same host.

  • –ipc=host: This option shares the host’s shared memory mechanism with the containers. Without it, Fast DDS will identify both containers as the same host, but since they will have separate shared memory spaces, they will not be able to communicate with one another. The use of this option is the Docker recommended way of sharing shared memory between containers, in opposition of for instance sharing the /dev/shm volume in Linux machines. A more advanced user could set the flag to shared, thus sharing the shared memory mechanism of one of the container with the others.

docker run -it --rm --network=host --ipc=host [OPTIONS] <docker-image>

1.2. Fast DDS Image

This Docker image contains the Fast DDS library and its dependencies, ready to be used in a final user application. This includes:

To load this image into your Docker repository, from a terminal, run:

docker load -i "ubuntu-fastdds <FastDDS-Version>.tar"

You can run this Docker container as follows:

docker run -it ubuntu-fastdds:<FastDDS-Version>

From the resulting Bash Shell you can run each feature.

1.2.1. Fast DDS Examples

Included in this Docker container is a set of binary examples that showcase several functionalities of the Fast DDS libraries. These examples’ path can be accessed from a terminal by typing:

goToExamples

From this folder, you can access all examples, both for DDS and RTPS layers.

1.2.1.1. Hello World Example

This is a minimal example that will perform a Publisher/Subscriber match and start sending samples.

goToExamples
cd hello_world/bin
tmux new-session "./hello_world publisher" \; \
     split-window "./hello_world subscriber" \; \
     select-layout even-vertical

This example is not constrained to the current instance. It’s possible to run several instances of this container to check the communication between them by running the following from each container.

goToExamples
cd hello_world/bin
./hello_world publisher

or

goToExamples
cd hello_world/bin
./hello_world subscriber

1.3. Fast DDS Suite Image

This Docker image contains the complete Fast DDS suite. This includes:

  • eProsima Fast DDS libraries and examples: Fast DDS libraries bundled with several examples that showcase a variety of capabilities of eProsima’s Fast DDS implementation.

  • Shapes Demo: eProsima Shapes Demo is an application in which Publishers and Subscribers are shapes of different colors and sizes moving on a board. Each shape refers to its own topic: Square, Triangle or Circle. A single instance of the eProsima Shapes Demo can publish on or subscribe to several topics at a time.

    You can read more about this application on the Shapes Demo documentation page.

  • Fast DDS Monitor: eProsima Fast DDS Monitor is a graphical desktop application aimed at monitoring DDS environments deployed using the eProsima Fast DDS library. Thus, the user can monitor in real time the status of publication/subscription communications between DDS entities. They can also choose from a wide variety of communication parameters to be measured (latency, throughput, packet loss, etc.), as well as record and compute in real time statistical measurements on these parameters (mean, variance, standard deviation, etc.).

    You can read more about this application on the Fast DDS Monitor documentation page.

  • DDS Router: eProsima DDS Router is an end-user software application that enables the connection of distributed DDS networks. That is, DDS entities such as publishers and subscribers deployed in one geographic location and using a dedicated local network will be able to communicate with other DDS entities deployed in different geographic areas on their own dedicated local networks as if they were all on the same network through the use of eProsima DDS Router. This is achieved by deploying a DDS Router on an edge device of each local network so that the DDS Router routes DDS traffic from one network to the other through WAN communication.

    You can read more about this application on the DDS Router documentation website.

  • Plotjuggler eProsima Edition: eProsima Fast DDS Visualizer Plugin is a plugin for the PlotJuggler application. PlotJuggler is a graphical desktop application providing visualization features of data series, time series, X-Y plots. It also adds data management features, such as data import and export, custom and built-in data manipulation functions, data series merges, etc. Also, this software supports many different layouts, with dynamic, rich and user-friendly customization.

    You can read more about this application on the Plotjuggler eProsima Edition documentation website.

To load this image into your Docker repository, from a terminal run

docker load -i "ubuntu-fastdds-suite <FastDDS-Version>.tar"

You can run this Docker container as follows

xhost local:root
docker run -it --privileged -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix \
ubuntu-fastdds-suite:<FastDDS-Version>

From the resulting Bash Shell you can run each feature.

1.3.1. Fast DDS Examples

Included in this Docker container is a set of binary examples that showcase several functionalities of the Fast DDS libraries. These examples’ path can be accessed from a terminal by typing

goToExamples

From this folder you can access all examples, both for DDS and RTPS. We detail the steps to launch two such examples below.

1.3.1.1. Hello World Example

This is a minimal example that will perform a Publisher/Subscriber match and start sending samples.

goToExamples
cd hello_world/bin
tmux new-session "./hello_world publisher" \; \
    split-window "./hello_world subscriber" \; \
    select-layout even-vertical

This example is not constrained to the current instance. It’s possible to run several instances of this container to check the communication between them by running the following from each container.

goToExamples
cd hello_world/bin
./hello_world publisher

or

goToExamples
cd hello_world/bin
./hello_world subscriber

1.3.2. Shapes Demo

To launch the Shapes Demo, from a terminal run

ShapesDemo

eProsima Shapes Demo usage information can be found on the Shapes Demo documentation.

1.3.3. Fast DDS Monitor

To launch the Fast DDS Monitor, from a terminal run

fastdds_monitor

eProsima Fast DDS Monitor user manual can be found on the Fast DDS Monitor documentation.

1.3.4. DDS Router

This example configures a DDS Router to communicate a publisher and subscriber running in different DDS Domains.

Run the following command to create the DDS Router yaml configuration file (/config.yml).

echo "version: v2.0
participants:
  - name: simple_dds_participant_0
    kind: local
    domain: 0
  - name: simple_dds_participant_1
    kind: local
    domain: 1" > /config.yml

Then execute the following command to run the Publisher in Domain 0, the Subscriber in Domain 1, and the DDS Router communicating both Domains.

goToExamples
cd configuration/bin
tmux new-session \
    "ddsrouter --config-path /config.yml" \; \
    split-window -h "./configuration publisher --domain 0 --interval 1000 --transport udp" \; \
    split-window -v "./configuration subscriber --domain 1 --transport udp"

eProsima DDS Router usage information can be found on the DDS Router documentation.

1.3.5. PlotJuggler eProsima Edition

To launch the PlotJuggler eProsima Edition, from a terminal run

plotjuggler

eProsima PlotJuggler eProsima Edition usage information can be located on the PlotJuggler eProsima Edition User Manual.

Dependencies and compatibilities

Fast DDS is continuously evolving and improving. This means that the different software products that are part of the Fast DDS ecosystem are evolving and improving together with Fast DDS. This section provides information about the required dependencies for building Fast DDS, as well as about the versions of the eProsima software products related to Fast DDS.

Platform support

This following definitions reflects the level of support offered by eprosima Fast DDS on different platforms:

  • Tier 1: these platforms are subjected to our unit test suite and other testing tools on a frequent basis including continuous integration jobs, nightly jobs, packaging jobs, and performance testing. Errors or bugs discovered in these platforms are prioritized for correction by the development team. Significant errors discovered in Tier 1 platforms can impact release dates and we strive to resolve all known high priority errors in Tier 1 platforms prior to new version releases.

  • Tier 2: these platforms are subject to periodic CI testing which runs both builds and tests with publicly accessible results. The CI is expected to be run at least within a week of relevant changes for the current release of Fast DDS. Installation instructions should be available and up-to-date in order for a platform to be listed in this category. Package-level binary packages may not be provided but providing a downloadable archive of the built workspace is encouraged. Errors may be present in released product versions for Tier 2 platforms. Known errors in Tier 2 platforms will be addressed subject to resource availability on a best effort basis and may or may not be corrected prior to new version releases. One or more entities should be committed to continuing support of the platform.

  • Tier 3: these platforms are those for which community reports indicate that the release is functional. The development team does not run the unit test suite or perform any other tests on platforms in Tier 3. Community members may provide assistance with these platforms.

Build system dependencies

The following table shows the minimum version required of the Fast DDS build system dependencies.

CMake

3.20

OS Architecture

amd64

amd32

arm64

Ubuntu Noble (24.04)

Tier 3: GCC 13.2

───

Tier 3: GCC 13.2

Ubuntu Jammy (22.04)

Tier 1: GCC 11.4
Tier 3: Clang 15

───

Tier 1: GCC 11.4
Tier 3: Clang 15

MacOS Mojave (10.14)

Tier 1: Clang 15

───

───

Windows 10

Tier 1: MSVC v142 (Visual Studio 2019)
Tier 3: MSVC v141 (Visual Studio 2017)

Tier 3: MSVC v142 (Visual Studio 2019)
Tier 3: MSVC v141 (Visual Studio 2017)

───

Windows 11

Tier 3: MSVC v143 (Visual Studio 2022)

Tier 3: MSVC v143 (Visual Studio 2022)

───

Debian Buster (10)

Tier 3: GCC 8

───

Tier 3: GCC 8

Android 12

Tier 3: SDK 31

───

Tier 3: SDK 31

Android 13

Tier 3: SDK 33

───

Tier 3: SDK 33

QNX 7.1

Tier 3: QCC (over GCC 8.3)

───

Tier 3: QCC (over GCC 8.3)

CMake

3.20

OS Architecture

amd64

amd32

arm64

Ubuntu Noble (24.04)

Tier 3: GCC 13.2

───

Tier 3: GCC 13.2

Ubuntu Jammy (22.04)

Tier 1: GCC 11.4
Tier 3: Clang 15

───

Tier 1: GCC 11.4
Tier 3: Clang 15

MacOS Mojave (10.14)

Tier 1: Clang 15

───

───

Windows 10

Tier 1: MSVC v142 (Visual Studio 2019)
Tier 3: MSVC v141 (Visual Studio 2017)

Tier 3: MSVC v142 (Visual Studio 2019)
Tier 3: MSVC v141 (Visual Studio 2017)

───

Windows 11

Tier 3: MSVC v143 (Visual Studio 2022)

Tier 3: MSVC v143 (Visual Studio 2022)

───

Debian Buster (10)

Tier 3: GCC 8

───

Tier 3: GCC 8

Android 12

Tier 3: SDK 31

───

Tier 3: SDK 31

Android 13

Tier 3: SDK 33

───

Tier 3: SDK 33

QNX 7.1

Tier 3: QCC (over GCC 8.3)

───

Tier 3: QCC (over GCC 8.3)

CMake

3.20

OS Architecture

amd64

amd32

arm64

Ubuntu Noble (24.04)

Tier 3: GCC 13.2

───

Tier 3: GCC 13.2

Ubuntu Jammy (22.04)

Tier 1: GCC 11.4
Tier 3: Clang 15

───

Tier 1: GCC 11.4
Tier 3: Clang 15

MacOS Mojave (10.14)

Tier 1: Clang 15

───

───

Windows 10

Tier 1: MSVC v142 (Visual Studio 2019)
Tier 3: MSVC v141 (Visual Studio 2017)

Tier 3: MSVC v142 (Visual Studio 2019)
Tier 3: MSVC v141 (Visual Studio 2017)

───

Windows 11

Tier 3: MSVC v143 (Visual Studio 2022)

Tier 3: MSVC v143 (Visual Studio 2022)

───

Debian Buster (10)

Tier 3: GCC 8

───

Tier 3: GCC 8

Android 12

Tier 3: SDK 31

───

Tier 3: SDK 31

Android 13

Tier 3: SDK 33

───

Tier 3: SDK 33

QNX 7.1

Tier 3: QCC (over GCC 8.3)

───

Tier 3: QCC (over GCC 8.3)

CMake

3.20

OS Architecture

amd64

amd32

arm64

Ubuntu Jammy (22.04)

Tier 1: GCC 11.4
Tier 3: Clang 15

───

Tier 1: GCC 11.4
Tier 3: Clang 15

Ubuntu Focal (20.04)

Tier 3: GCC 9

───

Tier 3: GCC 9

MacOS Mojave (10.14)

Tier 1: Clang 15

───

───

Windows 10

Tier 1: MSVC v142 (Visual Studio 2019)
Tier 2: MSVC v141 (Visual Studio 2017)

Tier 2: MSVC v142 (Visual Studio 2019)
Tier 2: MSVC v141 (Visual Studio 2017)

───

Windows 11

Tier 3: MSVC v143 (Visual Studio 2022)

Tier 3: MSVC v143 (Visual Studio 2022)

───

Debian Buster (10)

Tier 3: GCC 8

───

Tier 3: GCC 8

Android 12

Tier 3: SDK 31

───

Tier 3: SDK 31

Android 13

Tier 3: SDK 33

───

Tier 3: SDK 33

QNX 7.1

Tier 3: QCC (over GCC 8.3)

───

Tier 3: QCC (over GCC 8.3)

CMake

3.16

OS Architecture

amd64

amd32

arm64

Ubuntu Jammy (22.04)

Tier 1: GCC 9
Tier 3: Clang 12

───

Tier 1: GCC 9
Tier 3: Clang 12

Ubuntu Focal (20.04)

Tier 1: GCC 9
Tier 3: Clang 12

───

Tier 1: GCC 9
Tier 3: Clang 12

MacOS Mojave (10.14)

Tier 1: Clang 12

───

───

Windows 10

Tier 1: MSVC v142 (Visual Studio 2019)
Tier 2: MSVC v141 (Visual Studio 2017)

Tier 2: MSVC v142 (Visual Studio 2019)
Tier 2: MSVC v141 (Visual Studio 2017)

───

Debian Buster (10)

Tier 3: GCC 8

───

Tier 3: GCC 8

Android 11

Tier 3: SDK 30

───

Tier 3: SDK 30

QNX 7.1

Tier 3: QCC (over GCC 8.3)

───

Tier 3: QCC (over GCC 8.3)

CMake

3.16

OS Architecture

amd64

amd32

arm64

Ubuntu Focal (20.04)

Tier 1: GCC 9
Tier 3: Clang 12

───

Tier 1: GCC 9
Tier 3: Clang 12

MacOS Mojave (10.14)

Tier 1: Clang 12

───

───

Windows 10

Tier 1: MSVC v142 (Visual Studio 2019)
Tier 2: MSVC v141 (Visual Studio 2017)

Tier 2: MSVC v142 (Visual Studio 2019)
Tier 2: MSVC v141 (Visual Studio 2017)

───

Debian Buster (10)

Tier 3: GCC 8

───

Tier 3: GCC 8

Important

According to our release support guidelines Fast DDS v2.6.9 will be the last patch version receiving backported features and bugfixes. From now on, the v2.6 minor will only receive patches for critical issues and security fixes.

Library dependencies

The following table shows the corresponding versions of the Fast DDS library dependencies.

Important

According to our release support guidelines Fast DDS v2.6.9 will be the last patch version receiving backported features and bugfixes. From now on, the v2.6 minor will only receive patches for critical issues and security fixes.

eProsima products compatibility

The following table shows the compatibility between the different versions of the eProsima software products that use Fast DDS as the core middleware.

Important

According to our release support guidelines Fast DDS v2.6.9 will be the last patch version receiving backported features and bugfixes. From now on, the v2.6 minor will only receive patches for critical issues and security fixes.

Migration Guide to Fast DDS v3

This document aims to help during the migration process from eProsima Fast DDS version 2 to Fast DDS version 3. For more information about all the updates, please refer to the release notes.

Warning

Fast DDS v3 introduces a new feature XTypes that allows to discover remote types. In consequence, discovery traffic can be increased during start up. If you are experiencing high load during discovery, try disabling the new feature. Please refer to disable type propagation to learn how to do it.

Migration Steps

The following steps describe the possible changes that your project may require to migrate to Fast DDS v3.0.0:

Step 1: Update the package name and CMake configuration

  1. CMake project name: Rename all instances in the CMake project from fastrtps to fastdds. For example, update target_link_libraries(fastrtps) to target_link_libraries(fastdds), and if(NOT fastrtps_FOUND) to if(NOT fastdds_FOUND).

  2. Environment variables:

    • Rename FASTRTPS_DEFAULT_PROFILES_FILE to FASTDDS_DEFAULT_PROFILES_FILE.

    • The configuration file for loading profiles has been renamed from DEFAULT_FASTRTPS_PROFILES.xml to DEFAULT_FASTDDS_PROFILES.xml.

Step 2: Update dependencies

Fast DDS v3 is only compatible with Fast CDR v2. If you are not using Fast CDR as third-party, please ensure that your local dependencies are up-to-date. Refer to the library deprendencies table to verify version compatibility for all Fast DDS library dependencies.

Step 4: Apply namespace changes

  1. Namespace migration:

    • First, update all eprosima::fastrtps:: namespace references to eprosima::fastdds::.

    • Move built-in topics SubscriptionBuiltinTopicData, PublicationBuiltinTopicData, and ParticipantBuiltinTopicData from eprosima::fastdds::dds::builtin:: to eprosima::fastdds::rtps::.

    • Move Duration_t and c_TimeInfinite references from eprosima::fastdds:: to eprosima::fastdds::dds.

    • Move Time_t.hpp references from eprosima::fastdds:: to eprosima::fastdds::dds.

    Ensure you update these namespace references across your code to avoid compilation errors.

  2. Renamed types:

    • Change EventKindBits:: references to EventKind::.

    • Change EventKindEntityId:: references to EntityId::.

    • Change StatisticsEventKind:: references to statistics::EventKind::.

    Refactor the type references as outlined above to maintain compatibility with the new version.

Step 5: Migrate public headers

  1. Header files location:

    All the headers in include/fastrtps were migrated to include/fastdds. In particular, the following list includes headers that have been relocated to different paths or whose implementations have been incorporated into other headers:

    Fast DDS v2 file include path

    Fast DDS v3 file include path

    fastdds/rtps/resources/ResourceManagement.hpp

    fastdds/rtps/attributes/ResourceManagement.hpp

    fastrtps/eProsima_auto_link.h

    fastdds/fastdds_auto_link.hpp

    fastrtps/attributes/ParticipantAttributes.h

    fastdds/dds/domain/qos/DomainParticipantExtendedQos.hpp

    fastrtps/Domain.h

    fastdds/dds/domain/DomainParticipantFactory.hpp

    fastrtps/log/Log.h

    fastdds/dds/log/Log.hpp

    fastrtps/qos/DeadlineMissedStatus.h

    fastdds/dds/core/status/DeadlineMissedStatus.hpp

    fastrtps/qos/IncompatibleQosStatus.hpp

    fastdds/dds/core/status/IncompatibleQosStatus.hpp

    fastrtps/qos/LivelinessChangedStatus.h

    fastdds/dds/core/status/LivelinessChangedStatus.hpp

    fastrtps/qos/QosPolicies.h

    fastdds/dds/core/policy/QosPolicies.hpp

    fastrtps/qos/ReaderQos.h

    fastdds/dds/subscriber/qos/ReaderQos.hpp

    fastrtps/qos/WriterQos.h

    fastdds/dds/publisher/qos/WriterQos.hpp

    fastrtps/qos/SampleRejectedStatus.hpp

    fastdds/dds/core/status/SampleRejectedStatus.hpp

    fastrtps/participant/Participant.h

    fastdds/rtps/participant/RTPSParticipant.hpp

    fastrtps/transport/TCPv4TransportDescriptor.h

    fastdds/rtps/transport/TCPv4TransportDescriptor.hpp

    fastrtps/transport/TCPv6TransportDescriptor.h

    fastdds/rtps/transport/TCPv6TransportDescriptor.hpp

    fastrtps/transport/UDPv4TransportDescriptor.h

    fastdds/rtps/transport/UDPv4TransportDescriptor.hpp

    fastrtps/transport/UDPv6TransportDescriptor.h

    fastdds/rtps/transport/UDPv6TransportDescriptor.hpp

    fastrtps/transport/UDPTransportDescritpor.h

    fastdds/rtps/transport/UDPTransportDescritpor.hpp

    fastrtps/transport/TCPTransportDescritpor.h

    fastdds/rtps/transport/TCPTransportDescritpor.hpp

    fastdds/rtps/common/Time_t.hpp in namespace{fastdds}

    fastdds/dds/core/Time_t.hpp in namespace{fastdds::dds}

    Also, the fixed_size_string.hpp implementation has been migrated from fastrtps/utils/fixed_size_string.hpp to fastcdr/cdr/fixed_size_string.hpp.

  2. File extensions:

    Rename file extensions from .h to .hpp.

Step 6: Handle removed or private headers

The following list contains headers that were previously in the include folder and have been relocated to the src/cpp folder. Since they are no longer public, it is not possible to include them in external projects:

  • ParticipantAttributes.hpp

  • ReplierAttributes.hpp

  • RequesterAttributes.hpp

  • PublisherAttributes.hpp

  • SubscriberAttributes.hpp

  • ProxyPool.hpp

  • Semaphore.hpp

  • MessageReceiver.hpp

  • BuiltinProtocols.hpp

  • shared_mutex.hpp

  • StringMatching.hpp

  • TimeConversion.hpp

  • DBQueue.hpp

  • ResourceEvent.hpp

  • TimedEvent.hpp

  • WriterProxyData.hpp

  • ReaderProxyData.hpp

  • ParticipantProxyData.hpp

  • XML Parser API

  • UnitsParser.hpp

  • RTPSMessageGroup.hpp

  • RTPSMessageCreator.hpp

  • CDRMessage.hpp

  • StatefulPersistentReader.hpp

  • StatefulReader.hpp

  • StatelessPersistentReader.hpp

  • StatelessReader.hpp

  • PersistentWriter.hpp

  • StatefulPersistentWriter.hpp

  • StatefulWriter.hpp

  • StatelessPersistentWriter.hpp

  • StatelessWriter.hpp

  • logging.h

  • Exception.h

  • Cryptography.h

  • Authentication.h

  • AccessControl.h

  • SecurityException.h

  • ChangeForReader.hpp

  • ReaderLocator.hpp

  • ReaderProxy.hpp

  • ServerAttributes.hpp

  • TopicAttributes.hpp

  • TypeLookupService.hpp

If your project previously included any of these headers, you will need to modify your implementation.

Step 7: Update API methods

The table below contains the list of API changes, showing the previous methods and the corresponding new ones introduced in Fast DDS v3. The new API methods achieve the same functionality, even though the signature of the method is different from the deprecated one.

Deprecated methods

New methods

xmlparser::XMLProfileManager::library_settings(LibrarySettingsAttributes&)

DomainParticipantFactory::get_instance()->set_library_settings(const LibrarySettings&)

fill_discovery_data_from_cdr_message(ReaderProxyData&, MonitorServiceStatusData&)

fill_discovery_data_from_cdr_message(SubscriptionBuiltinTopicData&, MonitorServiceStatusData&)

fill_discovery_data_from_cdr_message(WriterProxyData&, MonitorServiceStatusData&)

fill_discovery_data_from_cdr_message(PublicationBuiltinTopicData&, MonitorServiceStatusData&)

fill_discovery_data_from_cdr_message(ParticipantProxyData&, MonitorServiceStatusData&)

fill_discovery_data_from_cdr_message(ParticipantBuiltinTopicData&, MonitorServiceStatusData&)

on_participant_discovery(DomainParticipant*, ParticipantDiscoveryInfo&&, bool)

on_participant_discovery(DomainParticipant*, ParticipantDiscoveryStatus, ParticipantBuiltinTopicData&, bool&)

on_subscriber_discovery(DomainParticipant*, ReaderDiscoveryInfo&&, bool)

on_data_reader_discovery(DomainParticipant*, ReaderDiscoveryStatus, SubscriptionBuiltinTopicData&, bool&)

on_publisher_discovery(DomainParticipant*, WriterDiscoveryInfo&&, bool)

on_data_writer_discovery(DomainParticipant*, WriterDiscoveryStatus, PublicationBuiltinTopicData&, bool&)

onReaderDiscovery(RTPSParticipant*, ReaderDiscoveryInfo&&, bool)

on_reader_discovery(RTPSParticipant*, ReaderDiscoveryStatus, SubscriptionBuiltinTopicData&, bool&)

onWriterDiscovery(RTPSParticipant*, WriterDiscoveryInfo&&, bool)

on_writer_discovery(RTPSParticipant*, WriterDiscoveryStatus, PublicationBuiltinTopicData&, bool&)

onParticipantDiscovery(RTPSParticipant*, ParticipantDiscoveryInfo&&, bool)

on_participant_discovery(RTPSParticipant*, ParticipantDiscoveryStatus, ParticipantBuiltinTopicData&, bool&)

XMLProfileManager::loadXMLFile(string&)

DomainParticipantFactory::get_instance()->load_XML_profiles_file(string)

XMLProfileManager::loadDefaultXMLFile()

load_profiles()

XMLProfileManager::loadXMLFile(string)

load_XML_profiles_file(string&)

XMLProfileManager::loadXMLString(const char*, size_t)

load_XML_profiles_string(const char*, size_t)

XMLProfileManager::fillParticipantAttributes(const string&, ParticipantAttributes&, bool)

get_participant_qos_from_profile(string&, DomainParticipantQos&)

DynamicTypeBuilder XMLProfileManager::getDynamicTypeByName(string&)

get_dynamic_type_builder_from_xml_by_name(string&, DynamicTypeBuilder::_ref_type&)

XMLProfileManager::fillRequesterAttributes(string&, RequesterAttributes&)

get_requester_qos_from_profile(string&, RequesterQos&)

XMLParser::getXMLThroughputController(tinyxml2::XMLElement*, ThroughputControllerDescriptor&, uint8_t)

XMLParser::getXMLFlowControllerDescriptorList(tinyxml2::XMLElement*, FlowControllerDescriptorList&, uint8_t)

add_throughput_controller_descriptor_to_pparams(FlowControllerSchedulerPolicy, uint32_t, uint32_t)

add_flow_controller_descriptor_to_pparams(FlowControllerSchedulerPolicy, uint32_t, uint32_t)

get_payload(uint32_t, CacheChange_t&)

get_payload(uint32_t, SerializedPayload_t&)

release_payload(CacheChange_t&)

release_payload(SerializedPayload_t&)

registerWriter(RTPSWriter*, const TopicAttributes&, const WriterQos&)

register_writer(RTPSWriter*, const PublicationBuiltinTopicData&)

registerReader(RTPSReader*, TopicAttributes&, ReaderQos&)

register_reader(RTPSReader*, const SubscriptionBuiltinTopicData&, const ContentFilterProperty*)

updateWriter(RTPSWriter*, const TopicAttributes&, const WriterQos&)

update_writer(RTPSWriter*, const WriterQos&)

updateReader(RTPSReader*, const TopicAttributes&, const ReaderQos&, const ContentFilterProperty*)

update_reader(RTPSReader*, const ReaderQos, const ContentFilterProperty*)

getRTPSParticipantAttributes()

get_attributes()

bool write(void*)

ReturnCode_t write(void*)

bool write(void*, WriteParams&)

ReturnCode_t write(void*, WriteParams&)

SenderResource::send(const octet*, uint32_t, LocatorsIterator*, LocatorsIterator*, const chrono::steady_clock::time_point&)

SenderResource::send(vector<NetworkBuffer>, uint32_t, LocatorsIterator*, LocatorsIterator*, const chrono::steady_clock::time_point&)

RTPSMessageSenderInterface::send(CDRMessage_t*, chrono::steady_clock::time_point)

RTPSMessageSenderInterface::send(vector<NetworkBuffer>&, uint32_t&, chrono::steady_clock::time_point)

createRTPSWriter(RTPSParticipant*, EntityId_t&, WriterAttributes&, shared_ptr<IPayloadPool>&, shared_ptr<IChangePool>&, WriterHistory*, WriterListener*)

createRTPSWriter(RTPSParticipant*, WriterAttributes&, WriterHistory*, WriterListener*)

RTPSWriter::new_change(const function<uint32_t()>& dataCdrSerializedSize, ChangeKind_t, InstanceHandle_t)

WriterHistory::create_change(uint32_t, ChangeKind_t, InstanceHandle_t)

RTPSWriter::new_change(ChangeKind_t, InstanceHandle_t)

WriterHistory::create_change(ChangeKind_t, InstanceHandle_t)

RTPSWriter::release_change(CacheChange_t*)

WriterHistory::release_change(CacheChange_t*)

RTPSWriter::remove_older_changes(unsigned int)

WriterHistory::remove_min_change()

RTPSWriter::is_acked_by_all(const CacheChange_t*)

RTPSWriter::is_acked_by_all(const SequenceNumber_t&)

RTPSWriter::updateAttributes(const WriterAttributes&)

RTPSWriter::update_attributes(const WriterAttributes&)

RTPSWriter::getListener()

RTPSWriter::get_listener()

RTPSWriter::isAsync()

RTPSWriter::is_async()

WriterListener::onWriterMatched(RTPSWriter*, MatchingInfo&)

WriterListener::on_writer_matched(RTPSWriter*, const MatchingInfo&)

WriterListener::onWriterChangeReceivedByAll(RTPSWriter*, CacheChange_t*)

WriterListener::on_writer_change_received_by_all(RTPSWriter*, CacheChange_t*)

TypeLookupReplyListener::onWriterChangeReceivedByAll(RTPSWriter*, CacheChange_t*)

TypeLookupReplyListener::on_writer_change_received_by_all(RTPSWriter*, CacheChange_t*)

RTPSReader::getListener()

RTPSReader::get_listener()

RTPSReader::setListener()

RTPSReader::set_listener()

RTPSReader::expectsInlineQos()

RTPSReader::expects_inline_qos()

RTPSReader::isInCleanState()

RTPSReader::is_in_clean_state()

RTPSReader::getHistory()

RTPSReader::get_history()

RTPSReader::nextUnreadCache(CacheChange_t**, WriterProxy**)

RTPSReader::next_unread_cache()

RTPSReader::nextUntakenCache(CacheChange_t**, WriterProxy**)

RTPSReader::next_untaken_cache()

ReaderListener::onReaderMatched(RTPSReader*, MatchingInfo&)

ReaderListener::on_reader_matched(RTPSReader*, MatchingInfo&)

ReaderListener::onNewCacheChangeAdded(RTPSReader*, const CacheChange_t* const)

ReaderListener::on_new_cache_change_added(RTPSReader*, const CacheChange_t* const)

TopicDataType::getSerializedSizeProvider(const void* const, DataRepresentationId_t)

TopicDataType::calculate_serialized_size(const void* const, DataRepresentationId_t)

TopicDataType::createData()

TopicDataType::create_data()

TopicDataType::deleteData(void*)

TopicDataType::delete_data(void*)

TopicDataType::getKey(const void* const, InstanceHand*, bool)

TopicDataType::compute_key(const void* const, InstanceHand&, bool)

TopicDataType::setName(const char*)

TopicDataType::set_name(const string&)

char* TopicDataType::getName()

string& TopicDataType::get_name()

TypeSupport::calculate_serialized_size_provider(const void* const, DataRepresentationId_t)

TypeSupport::calculate_serialized_size(const void* const, DataRepresentationId_t)

get_key(void, InstanceHandle_t*, bool)

compute_key(SerializedPayload_t&, InstanceHandle_t&, bool)

DynamicPubSubType::createData()

DynamicPubSubType::create_data()

DynamicPubSubType::deleteData(void*)

DynamicPubSubType::delete_data(void*)

DynamicPubSubType::getKey(const void* const, InstanceHand*, bool)

DynamicPubSubType::compute_key(const void* const, InstanceHand&, bool)

DynamicPubSubType::getSerializedSizeProvider(const void* const, DataRepresentationId_t)

DynamicPubSubType::calculate_serialized_size(const void* const, DataRepresentationId_t)

Review your code for any APIs marked with the FASTDDS_DEPRECATED and FASTDDS_TODO_BEFORE macros. Note that these deprecated APIs have been removed in Fast DDS v3. Make the necessary updates to your implementation to ensure compatibility with the new version.

Step 8: Update structs, enums, and variables

As part of the Fast DDS migration, several structs, enums, and variables have been updated. You will need to modify your code to reflect these changes:

  1. Enum and Variable Changes:

    • Rename DiscoveryProtocol_t to DiscoveryProtocol.

    • Rename initialHeartbeatDelay to initial_heartbeat_delay.

    • Rename heartbeatPeriod to heartbeat_period.

    • Rename nackResponseDelay to nack_response_delay.

    • Rename nackSupressionDuration to nack_supression_duration.

    • Rename heartbeatResponseDelay to heartbeat_response_delay.

    • Rename initialAcknackDelay to initial_acknack_delay.

    • Rename expectsInlineQos to expects_inline_qos.

    • Rename m_typeSize to max_serialized_type_size.

    • Rename m_isGetKeyDefined to is_compute_key_provided.

    • Rename m_topicDataTypeName to topic_data_typename.

  2. Extend Built-in Topics:

    • SubscriptionBuiltinTopicData has been extended with additional fields to mimic those of ReaderProxyData.

    • PublicationBuiltinTopicData has been extended with additional fields to mimic those of WriterProxyData.

    • ParticipantBuiltinTopicData has been extended to include the product version and fields from ParticipantProxyData.

  3. Other Struct Changes:

    • SendBuffersAllocationAttributes has a new attribute to define the allocation configuration of the NetworkBuffers.

    • TypeConsistencyQos has been removed from DataReader, and the TypeConsistencyEnforcementQosPolicy and DataRepresentationQosPolicy have been added.

Step 9: Examples refactor

All examples in the Fast DDS project have been refactored to follow a consistent structure, having renamed files, restructured classes, and updated the overall format. If you have integrated any example into your own implementation, carefully review the updated examples to ensure compatibility with your project. As reference, consider the example Configuration.

Information about the release lifecycle can be found here.

Version 3.2.2 (latest)

This release includes the following fixes:

  1. Fix related_sample_identity handling in RPC for ROS 2 request messages

  2. Fix compilation in Windows using MinGW compiler

  3. Fix a crash error in XMLDynamicParser.cpp due to wstring_builder being created as nullptr

This release includes the following improvements:

  1. Add support for sequence types in IDLParser

  2. Improve efficiency of Discovery Server routines

  3. Always copy type_information in ReaderProxyData and WriterProxyData copy constructors

  4. Add Fast DDS v2.6.10 to supported releases

This release includes the following ci management updates:

  1. Force using asio from thirdparty in MacOS CI

  2. Update 2.6.x weekly Ubuntu image to Ubuntu 22.04

Important

When upgrading to version 3.2.2 it is highly recommended to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.4. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

See also

For further information about the corresponding versions of other products related to this Fast DDS version, please refer to the eProsima products compatibility section.

Supported versions

Version 3.2

Version 3.2.2 (latest)

This release includes the following fixes:

  1. Fix related_sample_identity handling in RPC for ROS 2 request messages

  2. Fix compilation in Windows using MinGW compiler

  3. Fix a crash error in XMLDynamicParser.cpp due to wstring_builder being created as nullptr

This release includes the following improvements:

  1. Add support for sequence types in IDLParser

  2. Improve efficiency of Discovery Server routines

  3. Always copy type_information in ReaderProxyData and WriterProxyData copy constructors

  4. Add Fast DDS v2.6.10 to supported releases

This release includes the following ci management updates:

  1. Force using asio from thirdparty in MacOS CI

  2. Update 2.6.x weekly Ubuntu image to Ubuntu 22.04

Important

When upgrading to version 3.2.2 it is highly recommended to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.4. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

Version 3.2.1

This patch release includes the following fixes:

  1. Reduce trace category when failing to unregister type

  2. Avoid sending statistics message with big messages and no fragmentation

This release includes the following improvements:

  1. Setup ROS 2 Easy Mode at participant creation

  2. Update CLI commands for Easy Mode

  3. Get correct Fast CDR related branch in CI

  4. Update excluded IDL files from Gen CI

This release includes the following test fixes:

  1. Fix MacOS nightly flaky tests

  2. IDL parsing tests included paths

  3. Fix Windows example tests in Debug and mitigate rtps example flakiness

Important

When upgrading to version 3.2.1 it is highly recommended to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.4. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

Version 3.2.0

This minor release includes the following features:

  1. Implementation of get_matched_publication/subscription() DataReader/Writer API

  2. Extended incompatible QoS for monitor service

  3. Transform locators using new machine_id PID

  4. New property to select preferred key agreement algorithm.

  5. Parse IDL file on DynamicTypeBuilderFactory::create_type_w_uri

  6. Fast DDS ROS2 Easy Mode

  7. Add RPC related interfaces

  8. Extend QoS in discovery data

This release includes the following improvements:

Transport:

  1. Check if SHM transport is disabled in LARGE_DATA modes

  2. Allow domain names (DNS) when parsing TCP locators XML elements

  3. Improve Blackbox TCP tests suite

  4. Decouple transport receivers creation using unique network flows

  5. Improve max_allocations calculation on SHM transport

  6. Improve SHM configuration on large data transports

Discovery:

  1. Improve PDPClients initialization

  2. Make the machine id the physical_data host info

  3. Filter interested readers on PDP writer

  4. Make *ProxyData inherit from *BuiltinTopicData and refactor it

  5. Flow controller configuration for built-in endpoints

Security:

  1. Improve OpenSSL lifecycle handling

  2. Use correct algorithm strings on PermissionsToken and IdentityToken

  3. Log any errors before cancel_init()

  4. Add test for security initialization error

Tests:

  1. Add test for a union using an alias with scope

  2. Tests for regression test: fix sequence of alias of primitives inside modules

Tools and examples:

  1. Add -v or --version to CLI command tool

  2. Enable Datasharing segments clean from CLI

  3. Update examples CMakeList to force default CMAKE_BUILD_TYPE

  4. Update Benchmark example

  5. Remove SHM option from discovery server example

Documentation:

  1. Roadmap update

  2. Update latest notes from 2.10.x to 2.10.6

  3. Update RELEASE_SUPPORT after v2.14.4 release

  4. Set 3.0.x as EOL

  5. Update RELEASE_SUPPORT after 3.0.2 release

  6. Correct examples on README

  7. Warn about XTypes in Fast DDS v3

Other:

  1. Rename RTPSParticipantImpl.h to RTPSParticipantImpl.hpp

  2. Update sqlite from 3.36.0 to 3.47.2

  3. Add modules support to idl_serialize

Release management:

  1. Add replace tag to package.xml

  2. Prepare for Release v3.2.0

Github CI management:

  1. Add Debug CI to master nightly job

  2. Run examples in Windows CI

  3. Update submodules when cloning Fast DDS on CI

  4. Split Windows nightly tests using name filter regex

  5. Add missing psutil python module in sanitizers CI

This release includes the following fixes:

  1. Fix CVE-2025-24807

  2. Remove unused code

  3. Fix destruction data-race on participant removal in intra-process

  4. SecurityManager fixes

  5. Address XMLDynamicParser regression

  6. Fix assertion deleting a DataWriter configured with persistent and flow controller

  7. Fix comparison in is_update_allowed()

  8. Fix build with -Werror=template-id-cdtor

  9. Fix commercial support link

  10. Fix cmake generator evaluation

  11. Fix reach of maximum buffers in asio::send_to

  12. Fix unique network flows with TCP transports

  13. Fix tsan potential deadlock between StatefulWriter and FlowController

  14. Fix Discovery CLI Tool in Windows

  15. Arithmetic overflow in fragment size calculations

  16. Fix double-locking issue in DataSharingListener

  17. Fix EDP reliability timings

  18. Handle socket buffer size setting when system's maximum exceeded

  19. Fix log category name macro collision in MacOS

  20. Reliable volatile change dropped when all history acked

  21. Increase max_blocking_time for services in Easy Mode

  22. Unacknowledged sample removed in KEEP_ALL mode

  23. Fix System Log error infinite loop when setting thread affinity

  24. Support compiler MSYS2-MinGW

  25. Fix python warning in shm CLI tool

  26. Fix error handling logic in try_setting_buffer_size

  27. Remove repeated header include and fix log

  28. Flush logs in CliDiscoveryManager destructor

  29. Fix cleanup race condition with exclusive and shared lock files

  30. Fix assertion on OutputTrafficManager

  31. Fix several_writers_on_unack_sample_removed flaky test

Important

When upgrading to version 3.2.0 it is highly recommended to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.4. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

Version 3.1

Version 3.1.2

This release includes the following fixes:

  1. Arithmetic overflow in fragment size calculations

  2. Fix EDP reliability timings

  3. Address parseXMLMemberDynamicType regressions

  4. Fix double-locking issue in DataSharingListener

  5. Fix Discovery CLI Tool in Windows (No privileges)

  6. Fix log category name macro collision in MacOS

  7. Handle socket buffer size setting when system’s maximum exceeded

  8. Decouple transport receivers creation using unique network flows

  9. Fix dropped samples on reliable writers

  10. System Log error: infinite loop when setting thread affinity fails

This release includes the following improvements:

  1. Benchmark example updated

  2. Update sqlite from 3.36.0 to 3.47.2

  3. Update submodules when cloning Fast DDS on CI

  4. Improve PDPClients initialization

  5. Log any errors before cancel_init()

  6. Add replace tag to package.xml

Important

When upgrading to version 3.1.2 it is highly recommended to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.3. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

Version 3.1.1

This patch release includes the following features in an ABI compatible manner:

  1. New property to select preferred key agreement algorithm

This release includes the following fixes:

  1. Fix reach of maximum buffers in asio::send_to

  2. Fix TCP discovery server locators translation

  3. Fix unique network flows with TCP transports

  4. Address OSS-Fuzz` regressions in XML parsers

  5. Fix DataReaderHistory regression

  6. Fix destruction data-race on participant removal in intra-process

  7. Several fixes in security plugins and SecurityManager

  8. Fix cmake generator evaluation

  9. Fix build with -Werror=template-id-cdtor

  10. Fix potential deadlock between StatefulWriter and FlowController

This release includes the following improvements:

  1. Update commercial support section in README

  2. Rename RTPSParticipantImpl.h to RTPSParticipantImpl.hpp

  3. Check if SHM transport is disabled in LARGE_DATA modes

  4. Improve Blackbox TCP tests suite

  5. Test examples on Windows CI

  6. Regenerate types with Fast DDS Gen 4.0.3

Important

When upgrading to version 3.1.1 it is highly recommended to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.3. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

Version 3.1.0

This minor release includes the following features in an ABI compatible manner:

  1. Allow running CI on external contributions

  2. Allow for all durability configurations

  3. Complete support for Dynamic Network Interfaces

  4. Add QoS getters from raw XML

This release includes the following improvements:

  1. Be less strict with parameter lengths

  2. Modify help command of XML CLI tool

  3. Register and propagate MonitorService status type object

  4. Add tests for TypeLookup service

  5. Convert Fast DDS v2 to v3 Migration Changes into a Step-by-Step User Guide

  6. Update asio version from 1.18.1 to 1.31.0

  7. Update nlohmann/json thirdparty version from 3.9.1 to 3.11.3

  8. Regenerate types with latest Fast DDS-Gen v4.0.2

  9. Update fastcdr submodule with latest release

  10. Update roadmap, release support and versions for v3.1.0 release

This release includes the following fixes:

  1. Update request reply example README

  2. Fix xtypes example segfault if XML environment var is not set

  3. Remove unused validMatching methods in EDP

  4. Add Regression test for Fast DDS-Gen Use different typename for collections of TK_UINT8 and TK_BYTE

  5. Update latest 2.10.x to 2.10.5

  6. Discard changes with big key-only payload and no key hash

  7. Add test for support of enumeration literal @value annotation

  8. Fix memory leak deleting TypeLookupManager

  9. Fix DynamicData union deserialization when no member is selected

  10. Split nightly jobs to one per workflow

  11. Add references to new nightly jobs per supported branch in README

  12. Change xsd files installation directory to share/fastdds and remove icons on windows uninstall

  13. Fix flow_controllers comparison in DomainParticipantQos equality operator

  14. Fix CreateTopicWithDifferentTypeName_negative flaky test

  15. Warn instead of fail when dds.communication.dynamic_interfaces cannot be built

  16. Fix wrong Data type referred in flow control example README

Important

When upgrading to version 3.1.0 it is required to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.2. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

Version 2.14

Version 2.14.4

Important

Fast DDS v2.14 is the last minor version of Fast DDS v2, the major release Fast DDS v3 is already out! Check out all the new features and improvements in <https://fast-dds.docs.eprosima.com/en/latest/>

# Fast DDS v2.14.4

This release includes the following features in an ABI compatible manner:

  1. Add unsigned specification to literals.

  2. Allow running CI on external contributions.

  3. Add references to new nightly jobs per supported branch in README.

This release includes the following improvements:

  1. Add Ubuntu weekly CI.

  2. Fix Windows CI and add vanilla build step in Ubuntu CI.

  3. Use eProsima-CI action to install Qt.

  4. Modify help command of XML CLI tool.

  5. Update commercial support section in README.

This release includes the following fixes:

  1. Mitigate LogTests.flush_n flakiness.

  2. Mitigate buffer recover test flakiness on mac.

  3. Fix Python version in sanitizers CI.

  4. Fix OSS fuzz build.

  5. Fix warning in OSS fuzz build.

  6. Change monitor service writer entity ID.

  7. Solve SecurityManager memory issue.

  8. Fix issue with exclusive ownership and unordered samples.

  9. Fix data race in TypeObjectFactory::get_instance.

  10. Fix: Secure simple participants with initial peers over TCP match.

  11. Remove double // in some installation paths.

  12. Discard changes with big key-only payload and no key hash.

  13. Fix DataReaderHistory regression.

  14. Fix Secure Discovery Server client disposals GUID and handshake_handle assertion.

  15. Fix issues in Dynamic Network Interfaces.

  16. Check if SHM transport is disabled in LARGE_DATA modes.

  17. Release participant_stateless secure builtin writer history change when authentication has finished.

  18. Improve OpenSSL lifecycle handling.

  19. Fix destruction data race on participant removal in intra-process.

  20. Be less strict with parameter lengths.

Note

When upgrading to version 2.14.4 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.3.1.

Version 2.14.3

Important

Fast DDS v2.14 is the last minor version of Fast DDS v2, take a look at Fast DDS v3!

This release includes the following features in an ABI compatible manner:

  1. Setting vendor_id on received CacheChange_t

This release includes the following improvements:

  1. Repository & CI improvements.

  2. Create InitialConnection for TCP Transport initial peers

This release includes the following fixes:

  1. Fix topic interference on liveliness_changed status

  2. Remove doxygen warnings

  3. Adjust doxygen so Fast DDS Python pydoc makes RTD build

  4. Fix compilation in Ubuntu 24.04 platforms

  5. Fix Latency test destruction

Note

When upgrading to version 2.14.3 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.3.0.

Version 2.14.2

Important

Fast DDS v2.14 is the last minor version of Fast DDS v2, take a look at Fast DDS v3!

This release includes the following features in an ABI compatible manner:

  1. Set DataSharing Qos policy in transmitted WriterProxyData and ReaderProxyData.

  2. New max_message_size property to limit the output datagrams size.

  3. Add XML configuration for Flow Controllers.

This release includes the following improvements:

  1. Repository & CI improvements.

  2. Do not require PYTHON_VERSION to be defined. in .bat files.

  3. Use %* instead of loop in .bat scripts.

  4. Use absolute paths when loading XML files.

  5. Bump Fast CDR submodule to version 2.2.2.

This release includes the following fixes:

  1. Handle errors when setting socket buffer sizes.

  2. Do not require Fast CDR v2 in examples.

  3. Fix Shared Memory Transport buffer recovery MacOS flaky test.

  4. Automatically unmatch remote participants on participant deletion.

  5. Bugfix: correct liveliness state in a multiple reader - one writer scenario.

  6. Only apply content filter to ALIVE changes.

  7. Properly delete builtin statistics writers upon delete_contained_entities().

  8. Fix doxygen warning about undocumented @param in deleted functions.

  9. Correctly initialize MatchingFailureMask constants to be used with the std::bitset API.

  10. Fix Discovery Server not connecting due to ports logic.

Note

When upgrading to version 2.14.2 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.3.0.

Version 2.14.1

Important

Fast DDS v2.14 is the last minor version of Fast DDS v2, take a look at Fast DDS v3!

This release includes the following features in an ABI compatible manner:

  1. Implement copy_from_topic_qos method (see Creating a DataWriter and see Creating a DataReader).

This release includes the following improvements:

  1. Set 2.12.x as EOL

  2. Use a plain switch for NetmaskFilterKind operator<<

  3. Set real TCP non_blocking_send limitation

  4. Increase ack waiting time in reliable_on_unack_sample_removed

  5. Enforce SHM ports open mode exclusions

  6. Force unlimited ResourceLimits if lower or equal to zero (see ResourceLimitsQosPolicy)

  7. Allow processing of AckNack submessages with count == 0

  8. Refactor IStatusQueryable and make monitor service interfaces private

  9. Internal refactor on port handling

  10. Improve ThreadSettingsQoS logging

  11. Run is_plain method with the corresponding data representation

  12. Address compilation issue for GLIBC version

  13. Repository and test improvements:

    1. Run Github Ubuntu CI on PRs

    2. Only run PRs CI when a review is requested

    3. Improve filtering of DNS tests

    4. Make sample_lost_be_dw_be_dr_fragments test less flaky

    5. Build Fast DDS Python bindings in Fast DDS Docs Github CI job

    6. Add check for XML API to PR template

    7. Refactor Github CI sanitizer related jobs

    8. Increase sleep to miss the deadline in macOS flaky tests

    9. Fix nightly sanitizer CI workflow name

    10. Improve xml loading method in fuzz_XMLProfiles

    11. Build ShapesDemo on Ubuntu Github CI

    12. Correctly set branches for reusable-sanitizers-ci

This release includes the following fixes:

  1. Address XMLProfiles fuzzer regressions

  2. Fix flaky Log tests

  3. Fix hidden overloaded virtual methods

  4. Effectively assert automatic/manual_by_participant liveliness

  5. Fix on_sample_lost notification on best-effort readers for fragmented samples

  6. Monitor service properly managing instances

  7. Fix CVE-2024-30258

  8. Fix Discovery Server over TCP using LocatorSelectorEntry

  9. Removed warning

  10. Make get_first_untaken_info() coherent with read()/take()

  11. Fix serialization of Data(w)/Data(r) in MonitorService

  12. Bugfix in DDSBlackboxTestsDataReader test

  13. Fix leak in SecurityManager::participant_volatile_message_secure_writer_

  14. Fix some leaks in XML DynamicTypes Parser

  15. Fix support for @key annotation in Dynamic types

  16. Fix SecurityTest unit tests memory error

  17. Fix Python Installation version in Github CI. Address failing system tests environment issues

Note

When upgrading to version 2.14.0 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.3.0.

Version 2.14.0

Important

Fast DDS v2.14 is the last minor version of Fast DDS v2, take a look at Fast DDS v3!

This release includes the following new features:

  1. Add netmask filter transport configuration

  2. Add interface allowlist and blocklist

  3. Expose Security Authentication plugin Handshake Properties

  4. Extend LARGE_DATA configuration options

  5. Allow single listening port on TCP

  6. OpenOutputChannels / CloseOutputChannels that receive a LocatorSelectorEntry

  7. Support GTest v1.14.0

  8. Update Fast CDR submodule to v2.2.0

  9. Update roadmap and release support

This release includes the following improvements:

  1. Ignore custom PIDs defined in Fast DDS when they are received from other vendors

  2. Add catch of out-of-range exception for thread settings port

  3. Explicitly pass vendor ID to readFromCdrMessage

  4. TCP transport improvements:

    1. TCPSendResources cleanup

    2. TCP non_blocking_send moved to TCPTransportDescriptor

  5. Various repository improvements and housekeeping:

    1. Migrate communication tests to the DDS API

    2. Migrate TCPReqRepHelloWorldReplier/Requester to the DDS API

    3. Update APIs in video performance tests to the DDS API

    4. Remove FASTDDS_TODO_BEFORE 2.14

    5. Remove use of deprecated FindPythonInterp

    6. Remove idl parser from .repos file

    7. Force usage of semicolon in FASTDDS_TODO_BEFORE macro

    8. Ubuntu example testing automation infrastructure

  6. Multiple Github CI improvements:

    1. Add nightly Ubuntu Github CI

    2. Improve CI version management

    3. Avoid running GitHub CI if PR has conflicts

    4. Migrate apt package installation to eProsima-CI action

    5. Include missing nightly for 3.0.x branch

    6. Adapt nightly jobs for all supported versions

    7. Pin CMake version and vm.mmap_rnd_bits in sanitizer workflows

    8. Select reusable workflow version depending on target branch in nightly jobs

This release includes the following fixes:

  1. Fix warnings when compiling for Windows x86

  2. TCP first message loss (see TCPTransportDescriptor)

  3. Fix warnings on tests on Windows 32bits

  4. Protect asio exception hotfix

  5. Fix CVE-2024-28231

  6. Github CI fixes:

    1. Fix CI documentation workflow label triggering

    2. Fix nightly jobs

    3. Fix input branch on reusable windows CI

    4. Use correct version of GTest on DS ASan tests

Note

When upgrading to version 2.14.0 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.3.0.

Version 2.10

Version 2.10.6

This release includes the following fixes:

  1. Remove double // in some installation paths

  2. Discard changes with big key-only payload and no key hash

  3. Fix DataReaderHistory regression

  4. Be less strict with parameter lengths

  5. Check if SHM transport is disabled in LARGE_DATA modes

  6. Fix issues in Dynamic Network Interfaces

This release includes the following improvements:

  1. Add references to new nightly jobs per supported branch in README

  2. Update commercial support section in README

  3. Modify help command of XML CLI tool

Github CI management:

  1. Allow running CI on external contributions

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.10.5

This release includes the following features in an ABI compatible manner:

  1. Add XML configuration for FlowControllerDescriptor

This release includes the following improvements:

  1. Use %* instead of loop in .bat scripts

  2. Documentation improvements

  3. Use absolute paths when loading XML files

  4. Reduce tests flakiness

  5. Add unsigned specification to literals

Github CI management:

  1. Set fallback branch for get_related_branch_from_repo correctly

  2. Fix sanitizers CI test summary report

  3. Run selected VS tool on Windows CI

  4. Use token for CCache action

  5. Refactor Fast DDS Ubuntu CI to include several tests

  6. Avoid CCache in some Github workflows

  7. Build profiling tests as alternate build in Ubuntu CI

  8. Add Ubuntu weekly CI

  9. Fix python version in sanitizers CI

  10. Fix windows CI and add vanilla build step in Ubuntu CI

  11. Use eProsima-CI action to install Qt

  12. Update types regeneration script homing path

This release includes the following fixes:

  1. Automatically unmatch remote participants on participant deletion

  2. Only apply content filter to ALIVE changes

  3. Fix liveliness state in a multiple reader - one writer scenario

  4. Fix topic interference on liveliness_changed status

  5. Fix DS servers not connecting due to ports logic

  6. Fix issue with exclusive ownership and unordered samples

  7. Fix SecurityManager memory issue

  8. Correctly initialize MatchingFailureMask constants to be used with the std::bitset API

  9. Fix data race in TypeObjectFactory::get_instance

  10. Properly delete builtin statistics writers upon delete_contained_entities()

  11. Fix secure simple participants with initial peers not matching over TCP

  12. Fix access violations on XML parser detected by OSS-fuzz

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.10.4

This release includes the following features in an ABI compatible manner:

  1. TCP Client and Server Participant Decision Making.

  2. Authentication Handshake Properties documentation.

  3. New max_message_size property to limit output datagrams size.

This release includes the following improvements:

  1. Return const reference in get_log_resources.

  2. Include variety of terminate process signals handler in discovery server.

  3. Check History QoS inconsistencies.

  4. Make DataWriters always send the key hash on keyed topics.

  5. LARGE_DATA Participants logic with same listening ports.

  6. Effectively assert AUTOMATIC/MANUAL_BY_PARTICIPANT liveliness.

  7. Improve checklist on PR template.

  8. Allow processing of AckNack submessages with count == 0.

  9. Internal refactor on port handling.

  10. Upgrade Fast CDR submodule to v1.0.28

TCP transport improvements:

  1. TCP non-blocking send.

  2. Enabling multiple interfaces through whitelist in TCP servers.

  3. Set real TCP non-blocking-send limitation.

  4. Clean up TCP send resources on peer disconnection.

Github CI management:

  1. Add macOS Github CI.

  2. Avoid running GitHub CI if PR has conflicts.

  3. Add Ubuntu Github CI.

  4. Improve CI version management.

  5. Pin CMake version and vm.mmap_rnd_bits in sanitizer workflows.

  6. Only run PRs CI when review is requested.

  7. Refactor Github CI sanitizer related jobs.

  8. Build ShapesDemo on Ubuntu Github CI.

  9. Fix Python version and environment.

  10. Add DNS entries to hosts files on Github workflows.

  11. Build Fast DDS Python bindings in Fast DDS Docs Github CI job.

This release includes the following fixes:

  1. Fix and refactor Windows Github CI.

  2. Fix wrong log info messages on TCP.

  3. Add a keyed fragmented change to the reader data instance only when complete.

  4. Prevent index overflow and correctly assert the end iterator in DataSharing.

  5. Fix the shared memory cleaning script.

  6. Fix CI documentation workflow label triggering.

  7. Add missing virtual destructor for StatisticsAncillary.

  8. Migrate apt package installation action to eProsima-CI.

  9. Add missing TypeLookup listeners.

  10. Fix doxygen docs warnings. Prepare for compiling with Doxygen 1.10.0.

  11. Upgrade dependency version to last patch version in .repos file.

  12. Fix TCP reconnection after open logical port failure.

  13. Avoid unhandled asio exceptions.

  14. Fix CVE-2024-28231.

  15. Fix data race on PDP.

  16. Fix flaky Log tests.

  17. Fix some flaky MacOS tests.

  18. Fix hidden overloaded virtual methods.

  19. Fix test filtering in CMake files.

  20. Avoid first message loss in TCP.

  21. Fix CVE-2024-30258 / CVE-2024-30259.

  22. Enforce SHM ports open mode exclusions.

  23. Force unlimited ResourceLimits if lower or equal to zero.

  24. Removed warning in ParameterList.

  25. Make DataReader::get_first_untaken_info() coherent with read()/take().

  26. Fix leak in SecurityManager.

  27. Fix support for @key annotation in DynamicTypes.

  28. Fix leaks in XML parser for DynamicTypes.

  29. Fix Discovery Server over TCP.

  30. Handle errors when setting socket buffer sizes.

  31. Fix on_sample_lost notification on best-effort readers for fragmented samples.

  32. Fix DataSharing QoS deserialization.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.10.3

This release includes the following features in an ABI compatible manner:

  1. Support Autofill port (automatically set a port) for TCP Transport.

  2. Define a super client by environment variable

  3. Support TCP Discovery server CLI and environment variable

  4. Define methods (environment variable, rtps layer, xml) to configure transport scenarios

  5. Custom pools on DDS layer (DataWriter and DataReader)

This release includes the following improvements:

  1. Log warning upon receiver resource creation failure

  2. Simplify code in CDRMessage

  3. Backport workflows from master

  4. Rerun failed tests with ctest option instead of colcon’s

  5. Use foonathan memory manager for reducing allocations in SharedMemManager.hpp

  6. Add CCache to all CI jobs

This release includes the following bugfixes:

  1. Fix RemoteBuiltinEndpointHonoring blackbox test

  2. Fix bad-free when receiving malformed DATA submessage

  3. Fix clang warnings

  4. Use STL implementation of Timed/RecursiveTimedMutex when MSVC >= 19.36

  5. Notify data-sharing listener at the end of a successful matching in intraprocess

  6. Fix the clang build for clang 14

  7. Fix HelloWorld Data-Sharing example idl

  8. Fix the behaviour of disable_positive_acks period

  9. Fix DomainParticipant::register_remote_type return when negotiating type

  10. Fix Data Race when updating liveliness changed in WLP

  11. Fix TCP sender resources creation

  12. Fix flow controllers unit tests compilation when using Fast CDR from thirdparty

  13. Add XML parser bit_bound bounds check

  14. Add tests for reconnection with same GUID

  15. Fix Github Windows CI

  16. Fix PubSubAsReliable test

  17. Use FASTRTPS_NO_LIB on unittest root folder

  18. Fix missing mandatory attribute check in XML parser struct type

  19. Fix mac address overflow on windows

  20. Use SO_EXCLUSIVEADDRUSE for Win32 unicast listening sockets

  21. Fix FileWatchTest for Github windows CI

  22. Add missing thread include

  23. Update TLS unit test certificates

  24. Select correct .repos file on push events

  25. Fix documentation CI branch

  26. Fix TCP deadlock on channel reuse

  27. Fix DNS filter in CMakeLists file for tests

  28. Fix bad-free when receiving malformed DATA_FRAG submessage

  29. Fix memory problem when ciphering payload

  30. Fix build with TLS, but not security

  31. Fix CVE-2023-50257

  32. Fix data race on writer destruction while sending heartbeat

  33. Fix comparison in remove_from_pdp_reader_history

  34. Fix data race in PDPListener and SecurityManager

  35. Update PR template to include check for PR description, title and backports

  36. Fix std::move warning

  37. Revert “TCP deadlock on channel reuse”

  38. Fix max clash with Windows CI

  39. Remove unnecessary TCP warning

  40. Discard already processed samples on PDPListener

  41. TCP unique client announced local port

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.10.2

This release includes the following improvements:

  1. Fix Data-Sharing delivery when data_count is zero

  2. Improve performance of intraprocess plus data-sharing

  3. Improve content filter expression parameters checks and verbosity

  4. Improve validation on PID_PROPERTY_LIST deserialization

  5. Participant ignore local endpoints

  6. Pick smallest available participant ID for new participants

  7. Improve endpoint QoS XML tags

  8. Forward compatibility with boost interprocess 1.74+

  9. Cap Thread Sanitizer memory usage to prevent runner shutdown

  10. Allow participant XML profile with no <rtps> tag

  11. Add unsupported note in API documentation to new ignore DomainParticipantListener callbacks

  12. Add documentation version fallback

This release includes the following bugfixes:

  1. Fixed long-standing reconnection issue on SHM transport

  2. Fix null dereference when fuzzing

  3. Fix segfault when creating two participant with same fixed id

  4. Fix UBSan (Undefined Behavior Sanitizer) issues

  5. Fix listener selection for on_requested_deadline_missed

  6. Fix build on msvc 19.36.32528

  7. Fix XML schema to set Transport descriptor kind as NOT mandatory

  8. Fix missing includes

  9. Fix overhead time unit

  10. Fix request reply example spelling typo

  11. Fix topic deletion after endpoint in examples

  12. Fix Data-Sharing delivery when data_count is zero

  13. Wait for log background thread initialization on the first queued entry

  14. Fix alias resolve in DDSSQLFilter

  15. Fix partition copy in QoS

  16. Fix StatelessWriter locators filtering

  17. Fix XMLParser null-dereference in parseLogConfig

  18. Fix encapsulation format in WLP

  19. Replace uint64_t by 8 in alignas specifier

  20. Capture all Fast CDR exceptions

  21. Security module: Honor allow_unauthenticated_participants flag

  22. Explicitly register type object in ContentFilteredTopicExample

  23. Avoid double definition of FASTDDS_ENFORCE_LOG_INFO

  24. Fix API Fast DDS v2.10.0 API break calling correctly on_participant_discovery callbacks

  25. Remove mutex from TimedEventImpl

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.10.1

This release includes the following feature in an ABI compatible way:

  1. ignore_participant() implementation

This release includes the following bugfixes:

  1. Fix repeated matched event notification.

  2. Fix regression introduced by #3396.

  3. Initial acknack backoff.

  4. Fix regular expression in XML schema.

  5. Correctly assign multicast port to multicast initial peers.

This release includes the following CI improvements:

  1. Update runner and GCC version for Thread Sanitizer job.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.10.0

This minor release includes several new features, improvements and bugfixes.

Note

Mind that, even though this release is API compatible with previous v2.x versions, it is NOT ABI compatible with previous versions. This means that applications upgrading Fast DDS to v2.10.0 will require recompilation, though not source code modification.

Note

It is also advisable to regenerate the type support from the IDL files using Fast DDS-Gen v2.4.0. Furthermore, if upgrading to v2.10.0, it is also recommended to upgrade Fast CDR to v1.0.27.

This release includes the following features:

  1. New on_unacknowledged_sample_removed callback in DataWriterListener.

  2. Secure Discovery Server.

  3. DomainParticipant ignore empty API.

  4. RTPS ReaderListener::on_incompatible_type and WriterListener::on_incompatible_type empty API.

This release includes the following improvements:

  1. Fast DDS improvements
    1. Improve behavior when STRICT_REALTIME CMake option is not enabled.

    2. Using functors for for_matched_readers parameter.

    3. Improve auto GAPs in Data Sharing.

    4. Use standard value for PID_RELATED_SAMPLE_IDENTITY.

  2. Contributions and repository quality
    1. Update Pull Request template.

    2. Update foonathan_memory quality declaration.

    3. Update XSD schema.

    4. Make network headers private avoiding exposing non-public API.

    5. Improve Doxygen documentation for ResourceLimitsQosPolicy.

  3. Examples
    1. New Request-Reply example.

  4. CI improvements
    1. New workflow to check documentation build.

    2. ASAN workflow updated to use Ubuntu 22.04.

  5. Dependencies
    1. Upgrade internal type supports using latest Fast DDS-Gen release v2.4.0.

    2. Upgrade Fast CDR submodule to v1.0.27.

  6. Fast DDS CLI
    1. Handle SIGTERM signal.

  7. Community supported platforms
    1. QNX 7.1 build infrastructure.

This release includes the following fixes:

  1. Security vulnerability
    1. Fix chain of trust issues with a single CA certificate.

  2. Bugfixes
    1. Fix RTPS StatelessWriter ACK check.

    2. ASAN (Address Sanitizer) fixes.

    3. UBSan (Undefined Behavior Sanitizer) fixes.

    4. Export public API correctly in Windows.

    5. Correctly handle builtin endpoints mask.

    6. Fix backwards compatibility using SHM communication.

    7. Protect against uncaught exception in SHM segment creation.

    8. Fix build for GCC 5.

    9. Validity check for first sequence number.

    10. Fix crash when enabling DisablePositiveACKsQoSPolicy with remote best-effort readers.

  3. Synchronization fixes
    1. Take mutex when removing local reader in WLP.

    2. Fix data races in SecurityManager authentication process.

  4. CI fixes
    1. Fix test building when using GTEST_INDIVIDUAL CMake option.

    2. Fix overflow in received samples in performance tests.

  5. Example fixes
    1. Avoid creating entities within callbacks in DynamicHelloWorldExample.

    2. Remove Asio dependency from DeadlineQoSExample.

  6. Repository fixes
    1. Remove 2.7.x as active branch.

  7. Community supported platforms
    1. Include right header when building for iOS.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.6 (maintenance)

Version 2.6.10 (maintenance)

Important

According to our release support guidelines the v2.6 minor will only receive patches for critical issues and security fixes.

This release includes the following critical fixes:

  1. Fix CVE-2025-24807

  2. Discard changes with big key-only payload and no key hash

  3. Update types regeneration script homing path

  4. Fix topic interference on liveliness_changed status

This release includes the following improvements:

  1. Add unsigned specification to literals

  2. Update commercial support section in README

  3. Update sqlite from 3.36.0 to 3.47.2

This release includes the following ci management updates:

  1. Exclude flaky tests when compiling without security

  2. Fix python version in sanitizers CI

  3. Fix Windows CI and add vanilla build step in Ubuntu CI

  4. Update submodules when cloning Fast DDS on CI

  5. Add Ubuntu weekly CI

  6. Allow running CI on external contributions

  7. Use eProsima-CI action to install Qt

  8. Add references to new nightly jobs per supported branch in README

Version 2.6.9

Important

According to our release support guidelines Fast DDS v2.6.9 will be the last patch version receiving backported features and bugfixes. From now on, the v2.6 minor will only receive patches for critical issues and security fixes.

This release includes the following features:

  1. Add XML configuration for FlowControllerDescriptor to 2.x

  2. New max_message_size property to limit output datagrams size

This release includes the following improvements:

  1. Update Fast CDR thirdparty submodule

  2. Consider library behavior changes as ABI breaks in the PR template checklist

  3. Allow processing of AckNack submessages with count == 0

  4. Use %* instead of loop in .bat scripts.

  5. Use absolute paths when loading XML files

  6. TCPSendResources cleanup

Github CI management:

  1. Fix Python Installation version in Github CI. Address failing system tests environment issues

  2. Set fallback branch for get_related_branch_from_repo correctly

  3. Fix sanitizers CI test summary report

  4. Protect asio exception

  5. Set Fallback branch to 2.6.x

  6. Run selected VS tool on Windows CI

  7. Add DNS entries to hosts files on Github workflows

  8. Refactor Fast DDS Ubuntu CI to include several tests

  9. Avoid CCache in workflows and nighties

  10. Update README.md with GitHub actions Ubuntu CI nightly

  11. Label flaky tests with xfail

This release includes the following fixes:

  1. Fix leak in SecurityManager::participant_volatile_message_secure_writer_

  2. Fix Discovery Server over TCP

  3. Fix some leaks in XML DynamicTypes Parser

  4. Correct liveliness state in a multiple reader - one writer scenario

  5. Fix support for @key annotation in Dynamic types

  6. Properly delete builtin statistics writers upon delete_contained_entities()

  7. Correctly initialize MatchingFailureMask constants to be used with the std::bitset API

  8. Set DataSharing in Writer|ReaderProxyData

  9. Only apply content filter to ALIVE changes

  10. Handle errors when setting socket buffer sizes

  11. Automatically unmatch remote participants on participant deletion

  12. Fix on_sample_lost notification on best-effort readers for fragmented samples

  13. Handle errors when setting socket buffer sizes

  14. Fix DS servers not connecting due to ports logic

  15. Manual fix for documentation generation

  16. Create InitialConnection for TCP initial peers

Version 2.6.8

This release includes the following features:

  1. Authentication Handshake Properties documentation.

  2. TCP Client and Server Participant Decision Making.

This release includes the following improvements:

  1. Make DataWriters always send the key hash on keyed topics.

  2. Include variety of terminate process signals handler in discovery server.

  3. Effectively assert AUTOMATIC/MANUAL_BY_PARTICIPANT liveliness.

  4. Pick smallest available participant ID for new participants.

  5. Check History QoS inconsistencies.

  6. Add check for XML API to PR template.

  7. LARGE_DATA Participants logic with same listening ports.

TCP transport improvements:

  1. TCP unique client announced local port.

  2. Remove unnecessary TCP warning and Fix some tests.

  3. TCP non-blocking send.

  4. Enabling multiple interfaces through whitelist in TCP servers.

  5. Set real TCP non-blocking-send limitation.

Github CI management:

  1. Refactor Github CI sanitizer related jobs.

  2. Avoid running GitHub CI if PR has conflicts.

  3. Add manual Ubuntu Github CI.

  4. Improve CI version management.

  5. Build ShapesDemo on Ubuntu Github CI.

  6. Only run PRs CI when review is requested.

  7. Add macOS and Ubuntu Github CI.

  8. Build Fast DDS Python bindings in Fast DDS Docs Github CI job.

  9. Pin CMake version and vm.mmap_rnd_bits in sanitizer workflows.

This release includes the following fixes:

  1. Fix and refactor Windows Github CI.

  2. Fix max clash with Windows CI.

  3. Fix the shared memory cleaning script.

  4. Fix doxygen docs warnings. Prepare for compiling with Doxygen 1.10.0.

  5. Prevent index overflow and correctly assert the end iterator in DataSharing.

  6. Add a keyed fragmented change to the reader data instance only when its completed.

  7. Add missing virtual destructor for StatisticsAncillary.

  8. Fix wrong log info messages on TCP.

  9. Migrate apt package installation action to eProsima-CI.

  10. Fix CI documentation workflow label triggering.

  11. Upgrade dependency version to last patch version in .repos file.

  12. Fix CVE-2024-28231

  13. Fix data race on PDP.

  14. Discard already processed samples on PDPListener.

  15. Fix flaky Log tests.

  16. Add missing TypeLookup listeners.

  17. Fix hidden overloaded virtual methods.

  18. Fix TCP reconnection after open logical port failure.

  19. Fix CVE-2024-30258 / CVE-2024-30259

  20. Make DataReader::get_first_untaken_info() coherent with read()/take().

  21. Removed warning in ParameterList.

  22. TCP avoid first message loss.

Version 2.6.7

This release includes the following features:

  1. Support Autofill port (automatically set a port) for TCP Transport.

  2. Define a super client by environment variable

  3. Support TCP Discovery server CLI and environment variable

  4. Define methods (environment variable, rtps layer, xml) to configure transport scenarios

  5. Secure discovery server

This release includes the following improvements:

  1. Log warning message upon receiver resource creation failure.

  2. Add tests for reconnection with same GUID

  3. Use foonathan memory manager for reducing allocations in SharedMemManager.hpp

  4. Simplify code in CDRMessage.

  5. Rerun failed tests with ctest option instead of colcon’s.

  6. Several improvements on CI jobs.

  7. Upgrade CMake minimum requirement to 3.16.3

  8. Update PR checklist template. Backports and Description

This release includes the following bugfixes:

  1. Fix DomainParticipant::register_remote_type return when negotiating type.

  2. Fix RemoteBuiltinEndpointHonoring blackbox test.

  3. Allow participant profiles with no rtps tag.

  4. Fix bad-free when receiving malformed DATA submessage.

  5. Fix clang warnings

  6. Use STL implementation of Timed/RecursiveTimedMutex when MSVC >= 19.36.

  7. Fix encapsulation format in WLP.

  8. Fix the clang build for clang 14.

  9. Notify data-sharing listener at the end of a successful matching in intraprocess.

  10. Updatable disable_positive_acks period.

  11. Fix Data Race when updating liveliness changed in WLP.

  12. Fix TCP sender resources creation.

  13. Fix flow controllers unit tests compilation when using Fast CDR from thirdparty.

  14. Add XML parser bit_bound bounds check.

  15. Use FASTRTPS_NO_LIB on unittest root folder.

  16. Use SO_EXCLUSIVEADDRUSE for Win32 unicast listening sockets.

  17. Fix mac address overflow on windows.

  18. Fix PubSubAsReliable test.

  19. Fix FileWatchTest.

  20. Add missing thread include.

  21. Fix missing mandatory attribute check in XML parser struct type.

  22. Better handling of trigger events in docs CI.

  23. Fix memory problem when ciphering payload

  24. Select correct .repos file on push events

  25. Update TLS unit test certificates

  26. Fix bad-free when receiving malformed DATA_FRAG submessage

  27. Fix data race on writer destruction while sending heartbeat

  28. Fix DiscoveryServer list access deadlock

  29. Fix c++11 support for fast discovery server tool

  30. Fix CVE-2023-50257

  31. Fix std::move warning

  32. Fix Github Windows CI

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.6.6

This release includes the following improvements:

  1. Improve validation on PID_PROPERTY_LIST deserialization.

  2. Improved CPU usage of timed events thread.

  3. Improved performance on intraprocess + data-sharing.

  4. Explicitly register type object in ContentFilteredTopicExample.

  5. Improve installer generation with documentation version fallback.

  6. Improve content filter expression parameters checks and verbosity.

This release includes the following bugfixes:

  1. Fixed long-standing reconnection issues on SHM transport.

  2. Correctly resolve alias in DDSQLFilter.

  3. Fixed partition copy in QoS.

  4. Added length checks to prevent nullptr memory copy calls.

  5. Fixed XMLParser null-dereference when parsing log configuration.

  6. Fixed SHM in 32-bit architectures.

  7. Added missing include.

  8. Avoid double definition of FASTDDS_ENFORCE_LOG_INFO.

  9. Fixed statistics data_count with data-sharing.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.6.5

This release includes the following improvements:

  1. Improve behavior when STRICT_REALTIME CMake option is not enabled.

  2. Using functors for for_matched_readers parameter.

  3. Improve auto GAPs in Data Sharing.

This release includes the following bugfixes:

  1. Fix RTPS StatelessWriter ACK check.

  2. Fix total_read_ to be consistent with Reader’s History after DataReader::get_first_untaken_info().

  3. Add deprecation notice to ThroughputControllerDescriptor.

  4. UBSan (Undefined Behavior Sanitizer) fixes.

  5. Several dependencies fixes upgrading to Ubuntu 22.04.

  6. Fix chain of trust issues with a single CA certificate.

  7. Correctly handle builtin endpoints mask.

  8. Take mutex when removing local reader in WLP.

  9. Handle SIGTERM signal in Fast DDS CLI.

  10. Fix data races in SecurityManager authentication process.

  11. Avoid creating entities within callbacks in DynamicHelloWorldExample.

  12. Remove Asio dependency from DeadlineQoSExample.

  13. Validity check for first sequence number.

  14. Include right header when building for iOS.

  15. Fix build on MSVC 19.

  16. Correctly assign multicast port to multicast initial peers.

  17. Select correct listener for on_requested_deadline_missed().

  18. Forward compatibility with boost inter-process 1.74+.

  19. Fix missing includes when building with GCC 13.

  20. Honor allow_unauthenticated_participants flag.

  21. Capture all Fast CDR exceptions.

  22. Fix example to delete Topic after deleting the corresponding Endpoint.

  23. Protect against uncaught exception in SHM segment creation.

  24. Initial acknack backoff.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.6.4

This release includes the following bugfixes:

  1. Fix communication with asymmetric Ignore Participant flags.

  2. Fix deadlock in Writer Liveliness Protocol when using intraprocess.

  3. Fix notification lost.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.6.3

This release includes the following improvements:

  1. Upgrade CMake minimum requirement to 3.13.

  2. Improve Guid_t operator < performance.

This release includes the following bugfixes:

  1. Add python3 dependency to package.xml.

  2. Fix complex member printing for DynamicDataHelper.

  3. Fix selection of output locators.

  4. Fix null references on XML parser.

  5. Fix data races when creating DataWriters.

  6. Send GAPs correctly when using separate sending.

  7. Install Statistics IDL file.

  8. Fixes for building in older compilers.

  9. Fix deadlock when removing DomainParticipant when using SECURITY.

  10. Ensure shared_mutex implementation is consistent throughout supported platforms.

  11. Other minor fixes and improvements.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.6.2

This release includes the following improvements:

  1. Support for GCC 12.

  2. Overload DataReader::get_unread_count().

  3. Improve read/take performance when using topic with a great number of keys.

  4. Improve rediscovery on lossy environments.

This release includes the following bugfixes:

  1. Fixed several deadlocks and data races.

  2. Fixed validation on ParameterPropertyList_t.

  3. Fixed wrong usage of std::remove_if.

  4. Fixed acknowledgement in DataSharing.

  5. Other minor fixes.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.6.1

This release includes the following improvements:

  1. Support for writer side content filtering

  2. Support hexadecimal values on SQL filter

  3. Support for DataWriter::get_key_value()

  4. Support for DataReader::lookup_instance()

  5. Support for SampleLostStatus on DataReader

  6. Improved doxygen documentation

Some bugfixes are also included:

  1. Fixed several lock order inversion issues

  2. Fixed data race when closing UDP channels

  3. Fixed empty partition validation checks

  4. Fixed corner case with reliable writers and samples with a huge number of fragments

  5. Other minor fixes and improvements

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.6.0

This minor release is API compatible with the previous minor release, but introduces ABI breaks on two of the three public APIs:

  • Methods and attributes have been added on several classes of the DDS-PIM high-level API, so indexes of symbols on dynamic libraries may have changed. Some API is also being deprecated.

  • Methods and attributes have been added on several classes of the RTPS low-level API, so indexes of symbols on dynamic libraries may have changed.

  • Old Fast-RTPS high-level API remains ABI compatible.

This minor release includes the following features:

  1. Allow modifying remote server locators at runtime

  2. Add statistics physical information to DATA[p] using properties

  3. Content filter discovery information RTPS API

  4. Endpoint discovery RTPS API

  5. on_sample_lost RTPS API

  6. Transport layer API extension

  7. XML support for Fast DDS CLI

  8. New exchange format to reduce bandwidth in Static Discovery

It also includes the following improvements:

  1. Support lowercase keywords on SQL filter

  2. Separate initialization and enabling of BuiltinProtocols

  3. Add disable_positive_acks to Static Discovery XML

  4. Several updates in the DDS-PIM API

  5. Support for octet vectors on XML parser

  6. Update README and roadmap

  7. Update Fast-CDR submodule to v1.0.24

  8. Add new CMake option APPEND_PROJECT_NAME_TO_INCLUDEDIR

Some bugfixes are also included:

  1. Fix MatchedStatus last_*_handle

  2. Fix recommended statistics DataReaderQos to enable backwards compatibility

  3. Fixes for supporting Python bindings in Windows platforms

  4. Fix publishing physical data on statistics topic

  5. Other minor fixes and improvements

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Previous end-of-life versions

Version 3.0 (EOL)

Version 3.0.2

This release includes the following improvements:

  1. Add support for DLL export on Windows

  2. Modify help command of XML CLI tool

  3. Register and propagate MonitorService status type object

  4. Add tests for TypeLookup service

  5. Discard changes with big key-only payload and no key hash

  6. Improve on Step-by-Step User Guide from the Migration Guide

  7. Add test for support of enumeration literal

  8. Update new nightly jobs on README

  9. Change xsd files installation directory to share/fastdds and remove icons on Windows uninstall

  10. Update commercial support section in README

  11. Rename RTPSParticipantImpl.h to RTPSParticipantImpl.hpp

  12. Add new property to select preferred key agreement algorithm

  13. Improve OpenSSL lifecycle handling

  14. Improve Blackbox TCP tests suite

  15. Improve PDPClientsp initialization

  16. Update sqlite from 3.36.0 to 3.47.2

  17. Improve debugging process by adding logs before running SecurityManager::cancel_init()

  18. Update Benchmark example

  19. Add replace tag to package.xml

  20. Decouple transport receivers creation using unique network flows

  21. Support compiler MSYS2-MinGW

  22. Avoid redefinition warning for OPENSSL_API_COMPAT

Github CI management:

  1. Allow running CI on external contributions

  2. Add Windows CI example testing

  3. Update submodules when cloning Fast DDS on CI

  4. Add flow_control, rtps, custom_payload_pool and content_filter to Windows example CI testing

This release includes the following fixes:

  1. Fix CVE-2025-24807

  2. Update request reply refactored example README

  3. Fix xtypes example issue if XML environment variable was not set

  4. Fix length checks in the builtin decoder

  5. Remove unused validMatching methods in EDP

  6. Regression test for Fast DDS-Gen

  7. Fix memory leak issue deleting TypeLookupManager

  8. Fix issues in Dynamic Network Interfaces

  9. Fix wrong Data type referred in flow control example

  10. Address oss fuzz XMLParser regression

  11. Fix destruction data-race on participant removal in intra-process

  12. Fix DataReaderHistory regression

  13. Fix FASTDDS_SHM_TRANSPORT_DISABLED for LARGE_DATA modes

  14. Address XMLDynamicParser regression

  15. Fix SecurityManager assertion in Secure DS

  16. Fix issue on participant_stateless

  17. Fix comparison in is_update_allowed

  18. Fix -Werror=template-id-cdtor

  19. Fix TCP discovery server locators translation

  20. Fix cmake generator evaluation

  21. Fix TSAN potential deadlock by lock inversion

  22. Fix issue on NetworkBuffers

  23. Fix unique network flows with TCP transports

  24. Fix algorithm strings on PermissionsToken and IdentityToken

  25. Arithmetic overflow in fragment size calculations

  26. Address parseXMLMemberDynamicType regression

  27. Fix EDP reliability timings

  28. Fix null-dereference in parseXMLMemberDynamicType

  29. Fix double-locking issue in DataSharingListener

  30. Fix Discovery CLI Tool in Windows (No privileges)

  31. Fix socket buffer size configuration mechanism

  32. Fix issue on reliable volatile when all history acked

  33. Fix log category name macro collision in MacOS

  34. Fix issue of infinite loop when setting thread affinity fails

  35. Fix error handling logic in try_setting_buffer_size

  36. Fix call to on_unacknowledged_sample_removed when keep all history is used

Important

When upgrading to version 3.0.2 it is required to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.0. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

Version 3.0.1

This patch release includes the following improvements:

  1. Set string arguments as const references

  2. Improve resilience against clock adjustments

  3. Make Fast DDS build compatible with GCC 9

  4. Use eProsima-CI action to install Qt

  5. Update Fast CDR submodule to v2.2.4

  6. Regenerate types with Fast DDS Gen v4.0.1

This release includes the following fixes:

  1. Secure simple participants with initialpeers over TCP match

  2. Register also the minimal created from the received complete TypeObject in the TypeLookupService

  3. Fix issue with exclusive ownership and unordered samples

  4. Fix compilation error in Ubuntu 24.04

  5. Correct iterator increment after erasing elements in connected_servers_list

  6. Fix request reply example isolated build

Important

When upgrading to version 3.0.1 it is required to regenerate generated source from IDL files using at least Fast DDS-Gen v4.0.0. But it is advisable to regenerate them using the latest patch version of Fast DDS-Gen v4.0.x.

Version 3.0.0

Fast DDS v3.0.0 is a mayor release that entails some API breaks and new features. This version is not backwards compatible with previous versions. Refer to the migration guide for hints moving to Fast DDS v3.0.0.

This release includes the following API breaks:

  1. Fastrtps package name migration to fastdds.

  2. API and namespace migration from RTPS to DDS.

  3. Make private previously public API.

  4. Make all public headers .hpp.

  5. XTypes refactor.

  6. IPayloadPool refactor.

  7. Participant discovery structures refactor.

  8. GUIDLess Discovery Server.

  9. Gather-send implementation.

  10. const qualify all data related inputs in DataWriter APIs.

  11. Refactor RTPS reader APIs.

  12. Refactor RTPS writer APIs.

  13. Refactor RTPS WriterHistory.

  14. Refactor TopicDataType.

  15. Make StdoutErrConsumer default LogConsumer.

  16. All DataWriter::write overloads return ReturnCode_t type.

  17. Add XML configuration for FlowControllerDescriptor and remove ThroughputController.

  18. Move DataReader::TypeConsistencyEnforcement and DataReader::DataRepresentation from TypeConsistency to DataReaderQos.

  19. Migrate BuiltinEndpoints defines to variables.

  20. Remove string_convert header and source.

  21. Examples refactor.

  22. Update Fast DDS docs QoS examples.

  23. Link SHM locator kind with Fast DDS major version.

  24. Discard local SHM locators that cannot be opened.

This release includes the following new features:

  1. Type Propagation policy.

  2. Create Participant with default profile (use environment XML configuration).

  3. Create DomainParticipantExtendedQos class.

  4. Add product version on Participant Discovery information.

  5. Automatically unmatch remote participants on participant deletion.

  6. Refactor Statistics module IDL.

  7. Change PDP discovery database backup restore order.

  8. Create InitialConnection for TCP initial peers.

  9. New Maximum Message Size property to limit output datagrams size.

  10. Use PID_DOMAIN_ID during PDP.

  11. Ubuntu example testing automation infrastructure.

  12. Update versions in fastdds.repos file.

This release includes the following improvements:

  1. Make DataReader::return_loan return RETCODE_OK on loanable sequences without loans.

  2. Use absolute paths when loading XML files.

  3. Remove FASTCDR_VERSION_MAJOR == 1 related code.

  4. Setting vendor_id on received CacheChange_t.

  5. Builtin data related improvements.

  6. GitHub repository management.

  7. Migration guide.

  8. Update fastcdr thirdparty.

  9. Documentation updates due to major version change.

This release includes the following fixes:

  1. Handle errors when setting socket buffer sizes.

  2. Do not require PYTHON_VERSION to be defined in .bat files.

  3. Use %* instead of loop in .bat scripts.

  4. Set DataSharing in WriterProxyData and ReaderProxyData.

  5. Minor fix in DDSBlackboxTestsBasic.cpp.

  6. Fix PDP and EDP unittest compilation.

  7. Fix AllocTest compilation.

  8. Correct liveliness state in a multiple reader and one writer scenario.

  9. Only apply content filter to ALIVE changes.

  10. Fix compilation when building static library.

  11. Properly delete builtin statistics writers upon delete_contained_entities().

  12. Correctly initialize MatchingFailureMask constants to be used with the std::bitset API.

  13. Change monitor service writer entity id.

  14. Fix EDP build warning without security.

  15. Fix compilation warning.

  16. Fix discovery server not connecting due to ports logic.

  17. Fix assertion in TopicPayloadPool::release_history.

  18. Fix topic interference on liveliness_changed status.

  19. Fix typo in CMakeLists.txt.

  20. Solve SecurityManager memory issue.

  21. Fuzzer regressions and fix build issues.

  22. Address build issues for documentation and different platforms.

  23. Add unsigned specification to literals.

Important

When upgrading to version 3.0.0 it is required to regenerate generated source from IDL files using Fast DDS-Gen v4.0.0.

Version 2.13 (EOL)

Version 2.13.6 (EOL)

This release includes the following improvements:

  1. Create InitialConnection for TCP initial peers

  2. Only apply content filter to ALIVE changes

  3. Update version support documentation

  4. Add XML configuration for FlowControllerDescriptor

  5. Github CI improvements

This release includes the following fixes:

  1. Fix DS servers not connecting due to ports logic

  2. Correctly initialize MatchingFailureMask constants to be used with the std::bitset API

  3. Fix topic interference on liveliness_changed status

  4. Properly delete builtin statistics writers upon delete_contained_entities()

  5. Fix Latency tests

  6. Remove doxygen warnings

Note

When upgrading to version 2.13.6 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.2.1.

Version 2.13.5 (EOL)

This release includes the following features in an ABI compatible manner:

  1. New Maximum Message Size property to limit output datagrams size

This release includes the following improvements:

  1. Improve ThreadSettingsQoS logging

  2. Allow processing of AckNack submessages with count == 0

  3. Internal refactor on port handling

  4. Do not require PYTHON_VERSION to be defined in .bat files

  5. Use %* instead of loop in .bat scripts

  6. Consider library behavior changes as ABI breaks in the PR template checklist

  7. Refactor IStatusQueryable and make monitor service interfaces private

  8. Automatically unmatch remote participants on participant deletion

  9. Handle errors when setting socket buffer sizes

  10. Github CI management:

    1. Refactor Github CI sanitizer related jobs

    2. Build Fast DDS Python bindings in Fast DDS Docs Github CI job

    3. Build ShapesDemo on Ubuntu Github CI

    4. Fix Python Installation version in Github CI. Address failing system tests environment issues.

    5. Fix sanitizers CI test summary report

    6. Run selected VS tool on Windows CI

    7. Increase sleep to miss the deadline in macOS flaky tests

    8. Fix ShmTransport buffer recovery MacOS flaky test

    9. Set fallback branch for get_related_branch_from_repo correctly

    10. Add DNS entries to hosts files on github workflows

This release includes the following fixes:

  1. Add check for XML API to PR template

  2. Use absolute paths when loading XML files

  3. Fix some leaks in XML DynamicTypes Parser

  4. Force unlimited ResourceLimits if lower or equal to zero

  5. Enforce SHM ports open mode exclusions

  6. Run is_plain method with the corresponding data representation

  7. Removed warning

  8. Don’t require Fast CDR v2 in examples

  9. Make reader get_first_untaken_info() coherent with read() / take()

  10. Fix leak in SecurityManager::participant_volatile_message_secure_writer_

  11. Fix CVE-2024-30258 / CVE-2024-30259

  12. Fix support for @key annotation in Dynamic types

  13. Set DataSharing in Writer|ReaderProxyData

  14. Fix on_sample_lost notification on best-effort readers for fragmented samples

  15. Correct liveliness state in a multiple reader - one writer scenario

Note

When upgrading to version 2.13.5 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.2.1.

Version 2.13.4 (EOL)

This release includes the following features in an ABI compatible manner:

  1. Expose Authentication Handshake Properties

This release includes the following improvements:

  1. Monitor service properly managing instances

  2. Effectively assert AUTOMATIC / MANUAL_BY_PARTICIPANT liveliness

  3. Add catch of out-of-range exception for thread settings port

  4. TCP transport improvements:

    1. TCPSendResources cleanup

    2. TCP first message loss

    3. Set real TCP non_blocking_send limitation

This release includes the following fixes:

  1. Fix hidden overloaded virtual methods

  2. Fix Discovery Server over TCP using logical port

  3. Protect asio exception fix

  4. Fix flaky Log tests

  5. Fix CVE-2024-28231

  6. Add missing virtual destructor for StatisticsAncillary

  7. Increase ack waiting time in reliable_on_unack_sample_removed

  8. Fix versions in fastrtps.repos

  9. GitHub CI fixes:

    1. Fix CI version management

    2. Add manual Ubuntu Github CI

    3. Avoid running GitHub CI if PR has conflicts

    4. Migrate apt package installation action to eProsima-CI

    5. Only run PRs CI when review requested

    6. Pin CMake version and vm.mmap_rnd_bits in sanitizer workflows

    7. Improve filtering of DNS tests

Note

When upgrading to version 2.13.4 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.2.1.

Version 2.13.3 (EOL)

This patch release includes the following improvements:

  1. Enabling multiple interfaces through whitelist in TCP servers

  2. Set LARGE_DATA Participants logic with the same listening ports

  3. Check History QoS inconsistencies

This patch release includes the following fixes:

  1. Prevent index overflow and correctly assert the end iterator in DataSharing

  2. Fix the shared memory cleaning script

  3. Fix TCP reconnection after open logical port failure

  4. Fix data race on PDP

  5. Fix doxygen docs warnings. Prepare for compiling with Doxygen 1.10.0

  6. Add missing TypeLookup listeners

  7. Restore Blackbox tests names

  8. Add macOS Github CI

  9. Set 2.11.x as EOL

Note

When upgrading to version 2.13.3 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.2.1.

Version 2.13.2 (EOL)

This patch release includes the following fixes and improvements:

  1. Improve environment variable substitution algorithm

  2. Add large data to the Advanced Configuration example

  3. Discard already processed samples on PDPListener

  4. Ignore 0x8007 if coming from other vendor

  5. TCP unique client announced local port

  6. TCP non-blocking send

  7. TCP Client&Server Participant Decision-Making

  8. Add non-throwing getters for socket info

  9. Add a keyed fragmented change to the reader data instance only when it is completed

  10. Include a variety of terminate process signals handlers in the discovery server

  11. Make DataWriters always send the key hash on keyed topics

  12. Update Fast DDS types with Fast DDS Gen to include <cstdint> in v1 types

  13. Add serialization for Log::Kind to ostream

  14. Fix wrong log info messages on TCP

  15. Return const reference in get_log_resources

  16. Remove unnecessary warning

  17. Avoid a maybe-uninitialized warning

  18. Add static cast to an unused variable

  19. Prepare for v3.0.0 branch out

  20. Windows CI fixes

Note

When upgrading to version 2.13.2 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.2.1.

Version 2.13.1 (EOL)

Note

This release upgrades the following Fast DDS dependencies:

This release includes the following improvements:

  1. Downgrade CMake minimum required version to 3.20.

  2. Update PR template to include check for PR description, title and backports.

  3. Update Fast CDR submodule to v2.1.3.

This patch release includes the following fixes:

  1. Revert wrong fix for TCP deadlock on channel reuse.

  2. Fix wrong history selection when removing PDP samples.

  3. Fix data race when processing incoming PDP samples on different threads.

  4. Fix DNS test filter in CMakeLists.

  5. Fix deserialization of unions in generated code.

Note

When upgrading to version 2.13.1 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.2.1.

Version 2.13.0 (EOL)

Note

This release upgrades the following Fast DDS dependencies:

This release includes the following features:

  1. Support Monitor Service.

  2. Enable configuration of thread settings for all threads (both through the C++ API and XML configuration files).

  3. Support Autofill port (automatic assignment of a port) for TCP Transport listening port.

  4. Support TCP for Discovery Server CLI and environment variable.

  5. Usage of gtest_discover_tests.

  6. Define a super client by environment variable.

  7. Support adding interfaces to the interface whitelist by the name.

  8. Add new methods to configure Builtin Transport.

  9. Support DataRepresentationQos.

  10. Change serialize function default behavior to omit the data representation.

  11. Upgrade Fast CDR submodule to v2.1.2.

  12. Update roadmap & platforms support.

This release includes the following improvements:

  1. Rerun failed tests with ctest option instead of colcon’s.

  2. Add CCache to all CI jobs.

This release includes the following fixes:

  1. Fast DDS bugfixes

    1. Fix compilation of XMLProfileParserTests when building without security.

    2. Improve IgnoreNonExistentSegment test for Windows.

    3. Add missing thread includes.

    4. Fix warning in Mac rewarding unnecessary lambda capture.

    5. Use SO_EXCLUSIVEADDRUSE for Win32 unicast listening sockets.

    6. Fix gtest discovery timeout.

    7. Mark on_participant_discovery overload removal.

    8. Fix uninitialized member in BuiltinAttributes class.

    9. Fix set affinity directive for Android.

    10. Fix Monitor Service types & test without security.

    11. Fix TCP deadlock on channel reuse.

    12. Fix DNS filter in CMakeLists file for tests.

    13. Fix memory issues related to ciphering payload.

    14. Fix a bad-free when receiving a malformed DATA_FRAG submessage.

    15. Fix CVE-2023-50257.

    16. Fix compilation of Fast DDS Python tests.

    17. Fix data race on writer destruction while sending heartbeat.

    18. Fix build with TLS, when SECURITY=OFF and NO_TLS=OFF.

  2. CI fixes:

    1. Fix colcon on github CI.

    2. Better handling of trigger events in docs CI.

Note

When upgrading to version 2.13.0 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.2.0.

Version 2.12 (EOL)

Version 2.12.2 (EOL)

This release includes the following features:

  1. Methods to configure transport scenarios

  2. Support Autofill port (automatically set the port) for TCP Transport

  3. Support TCP for Discovery Server CLI and environment variable

  4. Define a super client by environment variable

  5. Change serialize function default behaviour to omit the data representation

  6. LARGE_DATA Participants logic with same listening ports

  7. TCP Client&Server Participant Decision-Making logic

  8. Expose Authentication Handshake Properties

  9. Enabling multiple interfaces through whitelist in TCP servers

  10. Add macOS and Ubuntu Github CI

This release includes the following improvements:

  1. Improve environment variable substitution algorithm

  2. Upgrade dependency version to last patch version in .repos file

  3. Rerun failed tests with ctest option instead of colcon’s

  4. Remove unnecessary TCP warning

  5. Update PR template to include check for PR description, title and backports

  6. Improvements in GitHub CI

This release includes the following fixes:

  1. Fix TCP reconnection after open logical port failure

  2. TCP unique client announced local port

  3. TCP non-blocking send

  4. Fix wrong log info messages on TCP

  5. Improve IgnoreNonExistentSegment test

  6. Use SO_EXCLUSIVEADDRUSE for Win32 unicast listening sockets

  7. Fix DNS filter in CMakeLists file for tests

  8. Fix bad-free when receiving malformed DATA_FRAG submessage

  9. Fix memory problem related to ciphering payload

  10. Fix CVE-2023-50257

  11. Fix build with TLS, but not security

  12. Fix comparison in remove_from_pdp_reader_history

  13. Fix data race in PDPListener and SecurityManager

  14. Discard already processed samples on PDPListener

  15. Fix .repos versions

  16. Fix the shared memory cleaning script

  17. Fix data race on writer destruction while sending heartbeat

  18. Return const reference to the shared pointer instead of a copy in get_log_resources

  19. Ignore 0x8007 if coming from other vendor

  20. Fix Doxygen docs warnings and prepare for compiling with Doxygen 1.10.0

  21. Include variety of terminate process signals handler in discovery server

  22. Add missing TypeLookup listeners

  23. Add a keyed fragmented change to the reader data instance only when its completed

  24. Fix data race on PDP

  25. Check History QoS inconsistencies

  26. Make DataWriters always send the key hash on keyed topics

  27. Prevent index overflow and correctly assert the end iterator in DataSharing

  28. Fix uninitialized member in RTPSParticipantAttributes

  29. Remove unnecessary std::move in FileWatch.hpp causing warning

  30. Add missing thread include

  31. Add missing virtual destructor for StatisticsAncillary

  32. Protect asio exception

  33. TCPSendResources cleanup

  34. Downgrade CMake version to 3.20

Version 2.12.1 (EOL)

This release includes the following improvements:

  1. Support for linking with Fast CDR v1.

  2. The period for the timer within the DisablePositiveACKsQosPolicy is now updatable.

  3. Log error message upon receiver resource creation failure.

  4. CI and repository improvements.

  5. Simplify code in CDRMessage.

This release includes the following fixes:

  1. Fast DDS bugfixes

    1. Fix transient local durability for reliable readers using intra-process and data-sharing.

    2. Use STL implementation of Timed/RecursiveTimedMutex when MSVC >= 19.36.

    3. Fix updatability of immutable DataWriterQos.

    4. Fix the clang build for clang 14.

    5. Fix remote locators filtering when whitelist provided.

    6. Fix Data Race when updating liveliness changed in WLP.

    7. Add XML parser bit_bound bounds check.

    8. Fix missing mandatory attribute check in XML parser struct type.

    9. SHM transport: ignore non-existing segment on pop.

    10. Fix: mac address overflow on Windows.

  2. CI fixes:

    1. Fix flow controllers unit tests compilation when using Fast CDR from thirdparty.

    2. PubSubAsReliable test fix.

    3. FileWatchTest fix for github windows CI.

Note

When upgrading to version 2.12.1 it is advisable to regenerate generated source from IDL files using Fast DDS-Gen v3.1.0.

Version 2.12.0 (EOL)

Note

This release upgrades the following Fast DDS dependencies:

Please, read also the release notes of Fast DDS-Gen v3.0.0 to be aware of every possible break in the application code.

As Fast DDS dependencies have been upgraded to new major releases, depending on the types defined in the IDL files, it might be required to modify the user application source code besides recompiling it (more information can be found in the corresponding release notes).

Note

There is a minor API break with previous v2.x versions: MEMBER_INVALID identifier was declared using #define. In order to prevent polluting the user workspace, it has been transformed into a constexpr within eprosima::fastrtps::types namespace.

This release includes the following features:

  1. New participant property to configure SHM transport metatraffic behavior.

  2. Exposed custom payload pool on DDS DataWriter and DataReader declaration.

    1. Feature example.

  3. Processing environment variables in XML text.

  4. Dependencies

    1. Upgrade internal type supports using latest Fast DDS-Gen release v3.0.0. This release introduces the following features:

      1. Support for @optional builtin annotation <optional_members>.

      2. Support for @extensibility builtin annotation <extensibility>.

    2. Upgrade Fast CDR submodule to v2.0.0 introducing XCDR encoding version 2.

This release includes the following improvements:

  1. fixed_string comparison operators.

  2. Remove mutex from TimedEventImpl (#3745, #3760)

  3. Performance improvements on intraprocess and datasharing.

  4. Improve Shared Memory resilience to crashing participants.

  5. Improve scripts shebang portability.

  6. Use foonathan_memory to reduce allocations in SharedMemManager.

This release includes the following fixes:

  1. Fast DDS bugfixes
    1. Fixed XMLParser null-dereference when parsing log configuration.

    2. Allow participant XML profiles with no <rtps> tag.

    3. Fix encapsulation format in Writer Liveliness Protocol.

    4. Fix DomainParticipant::register_remote_type return when negotiating type.

    5. Fix strict real-time feature when using Flow Controller feature.

    6. Fix ParameterPropertyList increment operators.

    7. Fix bad-free when receiving malformed DATA submessage.

    8. Fix asymmetric whitelist matching.

    9. Fix heap-use-after-free on XMLElementParser.

    10. Fix History remove change return statement.

  2. CI fixes
    1. Fix RemoteBuiltinEndpointHonoring blackbox test.

    2. Improve repository workflows.

    3. Use FASTRTPS_NO_LIB on unittest root folder.

    4. Fix Windows workflow.

  3. Tools
    1. Remove C++11 check in fastdds-discovery-server CLI tool.

  4. Examples
    1. Fix HelloWorldDataSharing data type.

  5. Documentation
    1. Doxygen typos.

  6. Repository
    1. Remove 2.9.x as active branch.

  7. Non Tier 1 support
    1. Fixed SHM in 32-bit architectures.

    2. Fix warning on Win32 architecture.

Note

Upgrading to version 2.12.0 requires to regenerate generated source from IDL files using Fast DDS-Gen v3.0.1.

Version 2.11 (EOL)

Version 2.11.3 (EOL)

This release includes the following features in an ABI compatible manner:

  1. Support Autofill port (automatically set a port) for TCP Transport.

  2. Define a super client by environment variable

  3. Support TCP Discovery server CLI and environment variable

  4. Define methods (environment variable, rtps layer, xml) to configure transport scenarios

  5. Custom pools on DDS layer (DataWriter and DataReader)

This release includes the following improvements:

  1. Allow participant profiles with no rtps tag

  2. Add Log warning message upon receiver resource creation failure, instead of an error

  3. Updatable disable_positive_acks period

  4. Backport workflows from master

  5. Update GitUtils.cmake

  6. Use foonathan memory manager for reducing allocations in SharedMemManager.hpp

  7. Rerun failed tests with ctest option instead of colcon’s

  8. Add CCache to all CI jobs

  9. Simplify code in CDRMessage

  10. TCP unique client announced local port

  11. Make DataWriters always send the key hash on keyed topics

  12. Include terminate process signals handler in discovery server

This release includes the following fixes:

  1. Fix encapsulation format in WLP used for the ParticipantMessageData

  2. Fix DomainParticipant::register_remote_type return when negotiating type

  3. Fix RemoteBuiltinEndpointHonoring blackbox test

  4. Fix .repos branches

  5. Fix bad-free when receiving malformed DATA submessages

  6. Fix clang warnings

  7. Use STL implementation of Timed/RecursiveTimedMutex when MSVC >= 19.36

  8. Fix the clang build for clang 14

  9. Fix HelloWorld DataSharing example idl

  10. Use FASTRTPS_NO_LIB on unittest root folder

  11. Fix Data Race when updating liveliness changed in WLP

  12. Fix TCP sender resources creation

  13. Fix flow controllers unit tests compilation when using Fast CDR from thirdparty

  14. Add XML parser bit_bound bounds check

  15. Fix branch selection on Github CI

  16. Better handling of trigger events in docs CI

  17. Use SO_EXCLUSIVEADDRUSE for Win32 unicast listening sockets

  18. Fix PubSubAsReliable test

  19. Fix FileWatchTest for Github windows CI

  20. Fix mac address overflow on windows

  21. Fix missing mandatory attribute check in XML parser struct type

  22. Update TLS unit test certificates

  23. Add missing thread include

  24. Add tests for reconnection with same GUID

  25. Notify data-sharing listener at the end of a successful matching in intraprocess

  26. Fix TCP deadlock on channel reuse

  27. TCP non-blocking send

  28. Fix DNS filter in CMakeLists file for tests

  29. Fix bad-free when receiving malformed DATA_FRAG submessage

  30. Fix memory problem when ciphering payload

  31. Fix CVE-2023-50257

  32. Fix build with TLS, but not security

  33. Fix std::move warning

  34. Update PR template to include check for PR description, title and backports

  35. Fix data race on writer destruction while sending heartbeat

  36. Fix comparison in remove_from_pdp_reader_history

  37. Fix data race in PDPListener and SecurityManager

  38. Fix an uninitialized value when building with GCC 13.2.0

  39. Fix max clash with Windows CI

  40. Discard already processed samples on PDPListener

  41. Remove unnecessary TCP warning

  42. Fix wrong log info messages on TCP

  43. Revert “TCP deadlock on channel reuse”

  44. Return const reference in get_log_resources

  45. Add a keyed fragmented change to the reader data instance only when it is completed

  46. Fix and refactor Windows Github CI

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.11.2 (EOL)

This release includes the following improvements:

  1. Improve Shared Memory resilience to crashing participants

  2. User configuration for Shared Memory metatraffic

  3. Performance improvements on intraprocess and data-sharing

This release includes the following fixes:

  1. Remove Mutex from TimedEventImpl

  2. Replace uint64_t by 8 in alignas specifier

  3. Fix XMLParser null-dereference in parseLogConfig

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.11.1 (EOL)

This release includes the following improvements:

  1. Correct CONTRIBUTING.md typo

  2. Improve validation on PID_PROPERTY_LIST deserialization

  3. Apply eProsima brand style to Fast DDS repository

  4. Fix spelling mistake: SUBSTRACTION to SUBTRACTION

This release includes the following fixes:

  1. Fixed long-standing reconnection issue on SHM transport

  2. Added missing include

  3. Fixed Boost handle usage regression

  4. Fix StatelessWriter locators filtering

  5. Avoid double definition of FASTDDS_ENFORCE_LOG_INFO

  6. Explicitly register type object in ContentFilteredTopicExample

  7. Properly handle zero-sized payloads on dynamic memory payload pools

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.11.0 (EOL)

This release includes the following features:

  1. Ignore every local endpoint within the DomainParticipant preventing local matching.

  2. Extend DynamicDataHelper API providing a print overload with std::ostream as parameter.

  3. TypeLookup Service settings.

  4. Static Discovery XSD Schema.

This release includes the following improvements:

  1. Fast DDS improvements
    1. Assign minimum available participant ID to new participants.

    2. Export symbols correctly on ContentFilteredTopic.

    3. Improve content filter expression parameters check and verbosity.

    4. Check TCP headers endianness.

    5. Security module: distinguished names (DN) comparison.

  2. Fast DDS deprecation
    1. DDS:Crypto:AES-GCM-GMAC configuration using Property Policy QoS (security vulnerability).

  3. CI improvements
    1. Include BitmapRange unit tests.

    2. Support for running some tests in parallel.

    3. Windows workflow.

  4. Build system
    1. Improve CMake target loading. Removal of FASTDDS_STATIC CMake option.

    2. Avoid auto-linkage using CMake.

  5. Dependencies
    1. Upgrade internal type supports using latest Fast DDS-Gen release v2.5.1.

    2. Upgrade Fast CDR submodule to v1.1.0.

  6. Examples
    1. Admit XML configuration files in AdvanceConfigurationExample.

    2. New Discovery Server example.

This release includes the following fixes:

  1. Fast DDS bugfixes
    1. Fix crash when creating two participants with the same fixed participant ID.

    2. Fix crash when calling on_requested_deadline_missed() callback.

    3. Fix crashes caused by not capturing every Fast CDR exception.

    4. Correctly resolve aliases in DDSSQLFilter.

    5. Wait for log background thread initialization on the first queued entry.

    6. Fix data race when accessing WRITE_PARAM_DEFAULT static variable.

    7. Fix partition copy in QoS.

    8. Fix Data-Sharing delivery when data_count is zero.

    9. Fix API Fast DDS v2.10.0 API break calling correctly. on_participant_discovery() callbacks.

    10. Security module: Honor Allow Unauthenticated Participants flag.

    11. Fix concurrent access to load_profiles().

    12. Fix UBSan (Undefined Behavior Sanitizer) issues.

    13. Improve Doxygen documentation about DomainParticipantListener discovery callbacks.

  2. XSD fixes
    1. Set TransportDescriptor kind parameter as optional.

    2. Correctly assign QoS to the proper endpoint.

    3. Add missing tags.

  3. CI fixes
    1. Fix null dereference in fuzzer code.

    2. Limit Thread Sanitizer memory usage to prevent runner shutdown.

    3. Use correct time unit in latency tests.

    4. Run communication tests.

  4. Examples
    1. Correct DDS entity deletion order.

  5. Installer generation
    1. Add documentation fallback when the documentation tag is not found.

  6. Repository
    1. Remove 2.1.x as active branch.

    2. Remove 2.8.x as active branch.

  7. Non Tier 1 support
    1. Fix build on MSVC 19.36.

    2. Forward compatibility with Boost inter-process 1.74+.

    3. Include missing header files required for compiling with GCC 13.

    4. QNX build fixes.

    5. Fix build issues in RPM systems.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.9 (EOL)

Version 2.9.2 (EOL)

This release includes the following ABI compatible improvements:

  1. Library improvements
    1. Improve behavior when STRICT_REALTIME CMake option is not enabled.

    2. Using functors for for_matched_readers parameter.

    3. Improve auto GAPs in Data Sharing.

    4. Improve content filter expression parameters check and verbosity.

    5. Improve validation on PID_PROPERTY_LIST deserialization.

  2. Fast DDS CLI
    1. Handle SIGTERM signal.

This release includes the following bugfixes:

  1. Security vulnerability
    1. Fix chain of trust issues with a single CA certificate.

  2. Library bugfixes
    1. Fix RTPS StatelessWriter ACK check.

    2. UBSan (Undefined Behavior Sanitizer) fixes.

    3. Fix backwards compatibility using SHM communication.

    4. Correctly handle builtin endpoint mask.

    5. Fix crash when enabling DisablePositiveACKsQosPolicy with remote best-effort readers.

    6. Validity check for first sequence number.

    7. ASAN (Address Sanitizer) fixes.

    8. Correctly assign multicast port to multicast initial peers.

    9. Protect against uncaught exception in SHM segment creation.

    10. Initial acknack backoff.

    11. Fix crash when calling on_requested_deadline_missed() callback.

    12. Security module: Honor allow_unauthenticated_participants flag.

    13. Fix crashes caused by not capturing every Fast CDR exception.

    14. Correctly resolve aliases in DDSSQLFilter.

    15. Wait for log background thread initialization on the first queued entry.

    16. Fix partition copy in QoS.

    17. Fix Data-Sharing delivery when data_count is zero.

    18. Fix StatelessWriter locators filtering.

    19. Avoid double definition of FASTDDS_ENFORCE_LOG_INFO.

    20. Fixed long-standing reconnection issue on SHM transport.

  3. CI fixes
    1. Fix test building when using GTEST_INDIVIDUAL CMake option.

    2. Use correct time unit in latency tests.

  4. Synchronization fixes
    1. Take mutex when removing local reader in WLP.

    2. Fix data races in SecurityManager authentication process.

  5. Example fixes
    1. Avoid creating entities within callbacks in DynamicHelloWorldExample.

    2. Remove Asio dependency from DeadlineQosExample.

    3. Correct DDS entity deletion order.

    4. Explicitly register TypeObject in ContentFilteredTopicExample.

  6. Installer generation
    1. Add documentation fallback when the documentation tag is not found.

  7. Non Tier 1 Support
    1. Fix build for GCC5.

    2. Fix build on MSVC 19.36.

    3. Include right header when building for iOS.

    4. Forward compatibility with Boost inter-process 1.74+.

    5. Include missing header files required for compiling with GCC13.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.9.1 (EOL)

This release includes the following bugfixes:

  1. Synchronization fixes:
    1. Fix deadlock in Writer Liveliness Protocol (WLP) using intraprocess.

    2. Fix data race in DomainParticipant::set_listener().

    3. Fix deadlock on TLS closure.

  2. Other fixes:
    1. Fix notification lost.

    2. Fix total_read_ to be consistent with Reader’s History after DataReader::get_first_untaken_info().

    3. Use shared pointers for internal singletons.

    4. Support CCache on Windows.

    5. Avoid null dereference on fuzzer.

    6. Other minor fixes and improvements.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.9.0 (EOL)

This minor release includes several new features (new log macros to avoid conflicts with external libraries), behavior change (default memory management policy is no longer PREALLOCATED_MEMORY_MODE, enable by default Fast DDS Statistics module but only taking statistics metrics if the corresponding Statistics DataWriter is enabled), performance improvements, CI improvements (including address sanitizer jobs), and several bug fixes.

Note

Mind that, even though this release is API compatible with previous v2.x versions, it is NOT ABI compatible with previous versions. This means that applications upgrading Fast DDS to v2.9.0 will require recompilation, though not source code modification.

Note

It is also advisable to regenerate the type support from the IDL files using Fast DDS-Gen v2.3.0. Furthermore, if upgrading to v2.9.0, it is also recommended to upgrade Fast CDR to v1.0.26.

This release includes the following features:

  1. New log macros EPROSIMA_LOG_INFO, EPROSIMA_LOG_WARNING and EPROSIMA_LOG_ERROR.

  2. Add ENABLE_OLD_LOG_MACROS CMake option to support disabling the compilation of previous log macros.

This release includes the following behavior changes:

  1. Default memory management policy set to PREALLOCATED_WITH_REALLOC_MEMORY_MODE.

  2. Statistics metrics are only calculated/accumulated when their corresponding DataWriter is enabled in Fast DDS Statistics Module.

  3. Enable FASTDDS_STATISTICS CMake option by default.

This release includes the following improvements:

  1. CI improvements:
    1. Add address sanitizer job for Fast DDS library.

    2. Add address sanitizer job for Discovery Server test suite.

  2. Upgrade Fast CDR submodule.

This release includes the following bugfixes:

  1. Synchronization fixes:
    1. Fix deadlock when removing remote DomainParticipants by expired liveliness when using Security.

    2. Protect DomainParticipant::set_listener() avoiding null reference.

    3. Fix data race on WriterProxy::stop while TimedEvent is being triggered.

    4. Protect creation/destruction of Boost’s named_mutex.

  2. CI fixes:
    1. Fix Statistics Module test suite.

    2. Fix recurring data races in test suite.

    3. Fix thread sanitizer job keeping Ubuntu 20.04.

  3. Other:
    1. Fix Topic creation when registering a type name different from the internal TypeSupport name.

    2. Fix communication with asymmetric Ignore Participant flags.

    3. Several dependencies fixes upgrading to Ubuntu 22.04.

    4. Disable error logged when DomainParticipant profile is not found.

    5. Fix CMake for Fast DDS use as submodule.

    6. Upgrade internal type supports generated with Fast DDS-Gen v2.3.0.

    7. Other minor fixes.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.8 (EOL)

Version 2.8.2 (EOL)

This release includes the following improvements:

  1. Add ASAN CI tests for Fast DDS and Discovery Server

  2. Mirror master onto both 2.8.x & 2.9.x

  3. Doxygen documentation: add deprecation notice to ThroughputControllerDescriptor

  4. Several fixes to remove warnings in Ubuntu Jammy (22.04)

  5. Improve behavior when HAVE_STRICT_REALTIME is not set

  6. Using functors in StatefulWriter.cpp for_matched_readers

  7. Fix build on old compilers

  8. Avoid creation of DynamicTypes on example

  9. Implement a validity check for firstSN

This release includes the following bugfixes:

  1. Fix bug in Topic creation with different Type Name

  2. Fix tests failing with subprocess aborted error

  3. Fix communication with asymmetric ignoreParticipantFlags

  4. Added ignore_participant_flags() to Blackbox_FastRTPS PubSubReader.

  5. Fix Deadlock in remove_participant (ResourceEvent thread) when compiled WITH_SECURITY

  6. Fix failed tests when compiling with statistics enabled

  7. Fix Windows StatistisQosTests.cpp linkage and Failed test

  8. Fixing deadlock in WLP

  9. Fix notification lost

  10. Fix StatelessWriter ACK check

  11. Fix total_unread_ consistent with reader’s history upon get_first_untaken_info()

  12. Fix chain of trust issues

  13. Fixed StatisticsSubmessageData unaligned access

  14. Fix build error when GTEST_INDIVIDUAL is OFF

  15. Correctly handle builtin endpoints mask

  16. Added missing mutex to WLP::remove_local_reader

  17. Handle SIGTERM in fast discovery server

  18. Improve auto gaps in data sharing

  19. Replaced SecurityManager temporary ProxyDatas with ProxyPools

  20. Fix crash when disable_positive_acks is enable and the remote reader is best-effort

  21. Protect from uncaught exception during SHM Segment creation

  22. Fix asio dependency

  23. Include the right header when building for iOS

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.8.1 (EOL)

This release includes the following bugfixes:

  1. Statistics module fixes:
    1. Increase statistics DataWriter history.

    2. Fix Statistics module CI.

    3. Install Statistics IDL file.

    4. Fix for building in old compilers.

    5. Fix core dumped in delete_contained_entities().

  1. Address sanitizer fixes:
    1. Add ASAN CI job and SANITIZE CMake option.

    2. Fixes reported by address sanitizer.

  1. Synchronization fixes:
    1. Fix data races when creating DataWriters.

    2. Ensure shared_mutex implementation is consistent throughout supported platforms.

  1. Other fixes:
    1. Include missing ReadCondition header.

    2. Fix selection of output locators.

    3. Fix null-dereference on parseXMLEnumDynamicType.

    4. Include 2.8.x branch release support.

    5. Send GAPs correctly when using separate sending.

    6. Fixes for building in old compilers.

    7. Fix DataReader::read_next_instance() and DataReader::take_next_instance() implementation.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.8.0 (EOL)

This minor release includes several new features, performance improvements (especially in the case of topics with many instances), CI improvements (including the ability to run the CI in Android emulators or devices), and several bug fixes.

Note

Mind that, even though this release is API compatible with previous v2.x versions, it is NOT ABI compatible with previous versions. This means that applications upgrading Fast DDS to v2.8.0 will require recompilation, though not source code modification.

Note

It is also advisable to regenerate the type support from the IDL files using Fast DDS-Gen v2.2.0. Furthermore, if upgrading to v2.8.0, it is also recommended to upgrade Fast CDR to v1.0.25.

This release includes the following features:

  1. Full Ownership and OwnershipStrength QoS support

  2. External locators

  3. UDPv6 support for fast-discovery-server tool and ROS_DISCOVERY_SERVER

  4. XML configuration support for statistics DataWriters QoS

  5. SNI support

  6. Propagate PropertyQoS properties when explicitly set

  7. Add API to createRTPSWriter with a custom pool

  8. Add std::string::compare API to fixed_string

  9. Get WAN address API in TCPv4 transport descriptors

  10. Adding DomainParticipantFactory::get_shared_instance() API

This release includes the following improvements:

  1. Performance improvements:
    1. Skip writer_removed processing for unaccounted instances

    2. Improve GUID_t operator< performance

  2. CI improvements:
    1. Add optional parameters to thread-sanitizer job

    2. Enable Android testing on device

  3. Examples:
    1. Update BasicConfigurationExample to allow set up TTL

    2. Add Guid info to BasicConfiguration Example cout

  4. Internal implementation improvements:
    1. Add script to generate idl files

    2. Group set_qos_from_attributes free functions into a separate file

    3. Update script for generating idl files

    4. Set last_heartbeat_count_ private member of WriterProxy as atomic

  5. Android Improvements

  6. Upgrade Fast CDR submodule

This release includes the following bugfixes:

  1. Synchronization fixes:
    1. Fix datarace using writer’s locator selectors

    2. Add lock guard at changing SHM port listener status members

    3. Add atomic variable to prevent datarace in FlowController

    4. Disable RTPSParticipantImpl after removing it from RTPSDomain participants list

    5. Fixing datarace on listener callbacks

    6. Protect access to reader listeners

    7. Use thread-safe localtime function in unix distributions

    8. Fixed usage of uninitialised ifreq

    9. Adding protection to id_counter access

  2. Repository fixes:
    1. Fix spelling mistake

    2. Add python3 dependency to package.xml

  3. Other:
    1. Fix null dereference on parseXMLBitsetDynamicType

    2. Change internal include path of nlohmann/json header file

    3. Instance allocation consistency

    4. Fix complex member printing for DynamicDataHelper

    5. Fix initialization order in mock

    6. Upgraded internal type supports

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.7 (EOL)

Version 2.7.2 (EOL)

This release includes the following improvements:

  1. Skip writer_removed processing for unaccounted instances.

  2. Improve GUID_t operator < performance.

This release also includes the following bugfixes:

  1. Fix complex member printing for DynamicDataHelper.

  2. Add python3 dependency.

  3. Fix selection of output locators.

  4. Fix data races when creating DataWriters.

  5. Fix null dereferences on XML parser.

  6. Send GAPs correctly when using separate sending.

  7. Install Statistics IDL file.

  8. Fixes for building in old compilers.

  9. Fix several deadlocks.

  10. Fix communication with asymmetric Ignore Participant flags.

  11. Fix notification lost.

  12. Fix StatelessWriter ACK check.

  13. Fix total_read_ to be consistent with Reader’s History after DataReader::get_first_untaken_info().

  14. Fix doxygen documentation adding deprecated to ThroughputControllerDescriptor.

  15. Several dependencies fixes upgrading to Ubuntu 22.04.

  16. Ensure shared_mutex implementation is consistent throughout supported platforms.

  17. Fix StatisticsSubmessageData unaligned access.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.7.1 (EOL)

This release includes the following features in an ABI compatible way:

  1. Checking STATIC EDP XML Files by means of DomainParticipantFactory::check_xml_static_discovery().

  2. ReadCondition implementation.

This release includes the following improvements:

  1. Thread sanitizer CI.

  2. Overload get_unread_count().

  3. Improve read/take performance when using topic with a great number of keys.

  4. Improve rediscovery on lossy environments.

  5. New CMake option USE_THIRDPARTY_SHARED_MUTEX.

  6. Notify changes in bulk in RTPS readers.

This release includes the following bugfixes:

  1. Fix Fast CDR submodule update to v1.0.24.

  2. Fix access to some pointers.

  3. Fixed validation on ParameterPropertyList_t.

  4. Fixed acknowledgement in DataSharing.

  5. Fixed wrong usage of std::remove_if.

  6. Suppress OpenSSL 3.0 warnings.

  7. Fixed race condition in Logging module.

  8. Other minor fixes and improvements.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.7.0 (EOL)

This release includes the following improvements:

  1. Support for DDS SampleRejectedStatus API

  2. Support for DDS DataWriter methods:

  1. Support for DDS find_topic()

  2. Support for GCC 12

  3. Upgrade CMake minimum requirement to 3.16.3

  4. Add Windows DLL support to Dynamic Types API

Some bugfixes are also included:

  1. Deadlocks and data races

  2. Move deprecated OpenSSL cleanup function to match the right version

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.5 (EOL)

Version 2.5.2 (EOL)

This release includes the following improvements:

  1. Support lowercase keywords and hexadecimal values on SQL filter.

  2. Support for GCC 12.

This release includes the following bugfixes:

  1. Fix MatchedStatus last_*_handle.

  2. Fix recommended statistics DataReaderQos to enable backwards compatibility.

  3. Fix deadlocks and data races.

  4. Fix empty partition validation checks.

  5. Fix corner case with reliable writers and samples with a huge number of fragments.

  6. Other minor fixes and improvements.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.5.1 (EOL)

This release includes the following improvements:

  1. ContentFilterTopic filtering at the DataReader side.

  2. Release lifecycle.

This release includes the following bugfixes:

  1. XML parser fixes.

  2. Discovery Server fixes.

  3. Fix DataSharing sample validation.

  4. PKCS#11 support fixes.

  5. Test fixes.

  6. Doxygen documentation fixes.

  7. GAP message fix.

  8. Enable memory protection on DataSharing readers.

  9. TCP reconnection issues.

  10. Fix dynamic network interfaces feature.

  11. Several Security module fixes.

  12. STRICT_REALTIME fix.

  13. Suppress OpenSSL 3.0 warnings.

  14. Move optionparser to thirdparty.

  15. Thread-safe access to endpoints collections.

  16. MemberDescriptor fully qualified name.

  17. Setting QoS fix.

  18. Other minor fixes and improvements.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.5.0 (EOL)

This minor release is API compatible with the previous minor release, but introduces ABI breaks on two of the three public APIs:

  • Methods and attributes have been added on several classes of the DDS-PIM high-level API, so indexes of symbols on dynamic libraries may have changed.

  • Methods and attributes have been added on several classes of the RTPS low-level API, so indexes of symbols on dynamic libraries may have changed.

  • Old Fast-RTPS high-level API remains ABI compatible.

This minor release includes the following features:

  1. Support for PKCS#11 format URIs for private keys

  2. Added interfaces for content filter APIs

  3. Allow new network interfaces to be detected at runtime

  4. New API on DataWriter to wait for a specific instance to be acknowledged

  5. Added interfaces for concatenation of transports

  6. Allow XML profiles to be loaded from a string

  7. Allow disabling piggyback heartbeat on XML and DataWriter QoS

  8. New basic configuration example

It also includes the following improvements:

  1. Working implementation of instance_state and view_state

  2. Allow zero-valued keys

  3. Made some type aliases public to ease python bindings integration

  4. Improved performance by avoiding unnecessary payload copies for samples that are going to be rejected

  5. Removed unnecessary headers from Log module public headers

  6. Add support for Key annotation in TypeObjectFactory

  7. Only export public symbols on non-windows platforms

  8. Some documentation improvements

Some important bugfixes are also included:

  1. Fixed payload pool handling on EDPSimple destructor

  2. Fixed null dereference on XML parser

  3. Correctly export XTypes related methods on Windows

  4. Ensure correct boost singleton destruction order

  5. Avoid warning when environment file filename is empty

  6. Correctly set GUID of DataWriter and DataReader upon creation

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.4 (EOL)

Version 2.4.2 (EOL)

This release includes the following improvements:

  1. Enable memory protection on DataSharing readers

  2. Add const overload of DataReader::guid()

  3. Set recommended statistics DataReaderQos to PREALLOCATED_WITH_REALLOC

  4. Allow fully qualified name on MemberDescriptor

This release includes the following bugfixes:

  1. Fix and refactor EDPSimple destructor

  2. Fix several build warnings on certain platforms

  3. Fix OSS fuzz issues

  4. Fix TCP synchronization issues

  5. Correct reporting of MatchedStatus last_*_handle

  6. Ensure correct boost singleton destruction order

  7. Fix inserting minimum CacheChange_t in GAP message

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 2.4.1 (EOL)

This release includes the following improvements:

  1. Fixed several flaky tests

  2. Improved bandwidth usage of GAPs and HEARTBEATs

  3. Correctly implement delete_contained_entities

  4. Use native inter-process on Windows

  5. Improved performance of unregister_instance

  6. Improved OSS-fuzz integration

  7. Support for partitions on DataWriterQoS and DataReaderQoS

  8. Some documentation improvements

  9. Removed unused macro to avoid naming clashes

This release includes the following bugfixes:

  1. Avoid bad_node_size exception when cross building

  2. Fixed build on old compilers

  3. Fixed buffers exhaustion when compiled with statistics

  4. Fixed runtime addition of Discovery Servers

  5. Fixed dangling sample references with big data

  6. Fixed history record issues with persistence

  7. Correctly disable DataReader on destruction

  8. Fixed alignment issues on XTypes QoS policies serialization

  9. Fixed reconnection to Discovery Server

  10. Correctly use builtin publisher for statistics DataWriters

  11. Fixed various GCC-11 warnings

  12. Use only public APIs from foonathan::memory

  13. Fixed installation directories for DDS examples

  14. Fixed read after free on security code

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.4.0 (EOL)

This minor release is API compatible with the previous minor release, but introduces ABI breaks on two of the three public APIs:

  • Methods and attributes have been added on several classes of the DDS-PIM high-level API, so indexes of symbols on dynamic libraries may have changed.

  • Methods and attributes have been added on several classes of the RTPS low-level API, so indexes of symbols on dynamic libraries may have changed.

  • Old Fast-RTPS high-level API remains ABI compatible.

This minor release includes the following features:

It also includes the following improvements:

  • Allow setting custom folder for data-sharing files.

  • Allow setting persistence guid with static discovery.

  • Check for NDEBUG in logInfo.

  • Removed old unused CMake code.

  • Fixed TLS behavior on TCP example.

  • Prepare API for easy integration of python bindings.

  • Improved statistics performance.

Some important bugfixes are also included:

  • Fixed order of returned samples on topics with keys.

  • Allow updating partitions to an empty set.

  • Correctly propagate DomainParticipantQos updates.

  • Avoid a volatile data-sharing reader to block a writer.

  • Correctly give priority to intra-process over data-sharing.

  • Fixed reallocation issue on LivelinessManager.

  • Fixed deadline issue on volatile DataWriter

  • Fixed STRICT_REALTIME silently not active with Unix POSIX systems.

  • Fixed build errors with OpenSSL 3.0

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.3 (EOL)

Version 2.3.6 (EOL)

This release includes the following improvements:

  1. Improve rediscovery on lossy environments.

  2. Upgrade CMake minimum requirement to 3.13.

  3. Improve Guid_t operator < performance.

This release includes the following bugfixes:

  1. Fixed validation on ParameterPropertyList_t.

  2. Add python3 dependency to package.xml.

  3. Fix null references and uncaught exceptions on XML parser.

  4. Install Statistics IDL file.

  5. Fix data races when creating DataWriters.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.3.5 (EOL)

This release includes the following improvements:

  1. Fixed several flaky tests.

  2. Use native inter-process on Windows.

  3. Support for partitions on DataWriterQoS and DataReaderQoS.

  4. Support for GCC 12.

  5. Correctly implement delete_contained_entities.

This release also includes the following bugfixes:

  1. Fixed deadline issue on volatile DataWriter.

  2. Allow updating partitions to an empty set.

  3. Fixed order of returned samples on topics with keys.

  4. Fixed issues in LivelinessManager.

  5. Correctly give priority to intra-process over data-sharing.

  6. Avoid bad_node_size exception when cross-building.

  7. Fixed build errors with OpenSSL 3.0.

  8. Avoid a volatile data-sharing reader to block a writer.

  9. Fixed history record issues with persistence.

  10. Correctly disable DataReader on destruction.

  11. Fixed various GCC 11 warnings.

  12. Fixed payload pool handling on EDPSimple destructor.

  13. Fixed read after free on security code.

  14. Fixed null dereference on XML parser.

  15. Ensure correct boost singleton destruction order.

  16. Enable memory protection on DataSharing readers.

  17. TCP reconnection issues.

  18. MemberDescriptor fully qualified name.

  19. Fix recommended statistics DataReaderQos to enable backwards compatibility.

  20. Fixed dangling sample references with big data.

  21. Fixed deadlocks and data races.

  22. Fixed reconnection to Discovery Server.

  23. Other minor fixes.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.3.4 (EOL)

This release includes the following improvements:

  1. Support of googletest using colcon

  2. Network latency reports source participant

  3. Update Fast DDS Gen to v2.0.2

This release includes the following bugfixes:

  1. Fix mutex lock count on PDPListener

  2. Limit SequenceNumberSet number of bits on deserialization

  3. Fix segmentation fault on discovery server

  4. Fix deadlock with security and timers

  5. Fix bug using not protected code in a test

  6. Fix deadlock with LivelinessManager

  7. Fix interval loop on events

  8. Fix run event when was cancelled

  9. Validate sequence range on CDRMessage::readSequenceNumberSet

  10. Fix subscription throughput data generation

  11. Allow examples to build on QNX

  12. Fix code on SHM clean

  13. Accept Statistics DataWriters in Discovery Server

  14. Fix read/take behavior when a future change is found

  15. Correctly handle deserialization errors on read_next_sample() / take_next_sample()

  16. Fixing SequenceNumberSet_t deserialization

  17. Proper history clean up when a reader unmatches a writer

  18. Unprotected code loaning samples

  19. Fix publication throughput statistic on volatile writers

  20. Fix Fast DDS CLI server name

  21. Several fixes in examples and tests

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.3.3 (EOL)

This release includes the following improvements:

  • Added more durability kinds in Static Discovery xml parser

  • Explicitly enable/disable data-sharing on performance tests

  • Allow fully qualified name in TypeDescriptor

  • Added missing DynamicData::get_union_id() method

  • Change log severity in DiscoveryServer first announcement

  • Several corrections to README

This release includes the following bugfixes:

  • Fixed warnings and segfaults on 32-bit platforms

  • Fixed UDPv6 behavior

  • Fixed persistence guid issue on statistics writers

  • Fixed static linking with open SSL

  • Fixed statistics header file inclusion

  • Fixed build on RedHat systems

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.3.2 (EOL)

This release includes the following feature:

  • Statistics Module

It also includes the following improvements:

  • Update Asio submodule and avoid exporting Asio API

  • Improve Windows installers

  • Ease Google Fuzz integration

  • Improve Doxygen documentation on lifetime of pointers created with RTPSDomain

  • Update Fast CDR to v1.0.21

This release includes the following bugfixes:

  • Add a correct multicast address for UDPv6

  • Recover from out-of-sync TCP datagrams

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.3.1 (EOL)

This release includes several bugfixes and improvements:

  • Added Fast DDS Statistics Module implementation

  • Fixed alignment issues on generated code calculation of maximum serialized size

  • Fixed calculation of data-sharing domain id

  • Fixed issues on data-sharing with volatile writers

  • Fixed build issues on old compilers

  • Fixed some tests when the library is built without security

  • Fixed and exposed pull mode on writers

  • Fixed handling of –data_sharing on latency test

  • Fixed calculation of memory pools sizes on debug builds

  • Correctly update memory policy on writers and readers

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.3.0 (EOL)

This minor release is API compatible with the previous minor release, but introduces ABI breaks on two of the three public APIs:

  • Methods and attributes have been added on several classes of the DDS-PIM high-level API, so indexes of symbols on dynamic libraries may have changed.

  • Methods and attributes have been added on several classes of the RTPS low-level API, so indexes of symbols on dynamic libraries may have changed.

  • Old Fast-RTPS high-level API remains ABI compatible.

This release adds the following features:

It also includes the following improvements:

  • Data-sharing delivery internal refactor

  • Additional metadata on persistence databases

  • Refactor on ReturnCode_t to make it switch friendly

  • Performance tests refactored to use DDS-PIM high-level API

  • Receive const pointers on delete_xxx methods

  • Discovery server improvements

  • Made SOVERSION follow major.minor

Some important bugfixes are also included:

  • Fixed shared memory usage on QNX

  • Fixed reference counting on internal pools

  • Fixed singleton destruction order

  • Fixed interoperability issues with x-types information

  • Fixed recovery of shared memory buffers

  • Lifespan support in persistent writers

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.2 (EOL)

Version 2.2.1 (EOL)

This release includes the following improvements:

  1. Data-sharing delivery internal refactor.

  2. Performance tests refactored to use DDS-PIM high-level API.

  3. Discovery server improvements.

This release includes the following bugfixes:

  1. Fixed reference counting on internal pools.

  2. Fixed singleton destruction order.

  3. Fixed default multicast locators.

  4. Fixed interoperability issues with x-types information.

  5. Fixed Reader history issues.

  6. Fixed data races issues.

  7. Fixed shared memory issues.

  8. Fixed heartbeat and ACK issues.

  9. Fixed LivelinessManager issues.

  10. Fixed TCP reception synchronization.

  11. Fixed build issues on old compilers.

  12. Allow modifying Partition QoS in enabled entities.

  13. Other minor fixes and improvements.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.2.0 (EOL)

This minor release is API compatible with the previous minor release, but introduces ABI breaks on two of the three public APIs:

  • Methods and attributes have been added on several classes of the DDS-PIM high-level API, so indexes of symbols on dynamic libraries may have changed.

  • Methods and attributes have been added on several classes of the RTPS low-level API, so indexes of symbols on dynamic libraries may have changed.

  • Old Fast-RTPS high-level API remains ABI compatible.

This release adds the following features:

  • Data Sharing delivery (avoids transport encapsulation for localhost communications)

  • Complete DDS-PIM high-level API declarations

  • Extension APIs allowing zero-copy delivery (both intra-process and inter-process)

  • Upgrade to Quality Level 1

It also includes the following improvements:

  • Code coverage policy

  • Added several tests to increase coverage

  • Increased GUID uniqueness

  • Allow logInfo messages to be compiled on build types other than debug

Some important bugfixes are also included:

  • Fixed timed events manager race condition

  • Fixed payload protection issues with SHM transport

  • Writers correctly handle infinite resource limits on keyed topics

  • Fixed unsafe code on AESGCMGMAC plugin

  • Several fixes for IPv6 (whitelists, address parser)

  • Fixes on liveliness timing handling

  • Fixed warnings building on C++20

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from any older version, regenerating the code is highly recommended.

Version 2.1 (EOL)

Version 2.1.4 (EOL)

This release includes the following improvements:

  1. Improve auto GAPs in Data Sharing

  2. Improve behavior when STRICT_REALTIME CMake option is not enabled

  3. Handle SIGTERM in fast discovery server CLI

This release includes the following bugfixes:

  1. Select correct listener for on_requested_deadline_missed

  2. Correctly assign multicast port to multicast initial peers

  3. Fix chain of trust issues with a single CA certificate

  4. Correctly handle builtin endpoints mask

  5. Fix build on MSVC 19

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 2.1.3 (EOL)

This release includes the following improvements:

  1. Improve rediscovery on lossy environments.

This release includes the following bugfixes:

  1. Fixed validation on ParameterPropertyList_t.

  2. Fixed SequenceNumberSet_t deserialization.

  3. Add python3 dependency to package.xml.

  4. Fix data races when creating DataWriters.

  5. Fix deadlock when removing remote DomainParticipants by expired liveliness when using Security.

  6. Fix communication with asymmetric Ignore Participant flags.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 2.1.2 (EOL)

This release includes the following improvements:

  1. Allow fully qualified name in TypeDescriptor.

  2. Use native inter-process on Windows.

  3. Support for GCC 12.

  4. Support of googletest using colcon.

This release also includes the following bugfixes:

  1. Fixed recovery of shared memory buffers.

  2. Fixed issues in LivelinessManager.

  3. Fixed default multicast locators.

  4. Fixed TCP issues.

  5. Fixed deadlocks and data races.

  6. Fixed deadline issue on volatile DataWriter.

  7. Avoid bad_node_size exception when cross-building.

  8. Fixed order of returned samples on topics with keys.

  9. Allow updating partitions to an empty set.

  10. Suppress OpenSSL 3.0 warnings.

  11. MemberDescriptor fully qualified name.

  12. Fixed history record issues with persistence.

  13. Fixed reconnection to Discovery Server.

  14. Other minor fixes.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 2.1.1 (EOL)

This release includes the following bugfixes:

  • Fixed race condition on security handshake

  • Fixed SHM data corruption when using both payload and sub-message protection

  • Fixed some interoperability issues

  • Fixed race condition on timed-events thread

  • Fixed usage of SHM on QNX systems

It also includes the following improvements:

  • Increased uniqueness of GUID prefix

  • Discovery server improvements

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 2.1.0 (EOL)

This minor release is API compatible with the previous minor release, but introduces ABI breaks on two of the three public APIs:

  • Methods and attributes have been added on several classes of the DDS-PIM high-level API, so indexes of symbols on dynamic libraries may have changed.

  • Methods and attributes have been added on several classes of the RTPS low-level API, so indexes of symbols on dynamic libraries may have changed.

  • Old Fast-RTPS high-level API remains ABI compatible.

Users of the RTPS low-level API should also be aware of the following API deprecations:

  • History::reserve_Cache has been deprecated

    • Methods RTPSWriter::new_change or RTPSReader::reserveCache should be used instead

  • History::release_Cache has been deprecated

    • Methods RTPSWriter::release_change or RTPSReader::releaseCache should be used instead

This release adds the following features:

  • Support persistence for large data

  • Added support for on_requested_incompatible_qos and on_offered_incompatible_qos

  • SKIP_DEFAULT_XML environment variable

  • Added FORCE value to THIRDPARTY cmake options

  • New log consumer (StdOutErrConsumer)

  • Added methods to get qos defined in XML Profile

  • Support for persistence on TRANSIENT_LOCAL

It also includes the following improvements:

  • Internal refactor for intra-process performance boost

  • Allow usage of foonathan/memory library built without debug tool

  • Large data support on performance tests

  • Reduced flakiness of several tests

Some important bugfixes are also included:

  • Fixed behavior of several DDS API methods

  • Fixed interoperability issues with RTI connext

  • Fixed DLL export of some methods

  • Avoid redefinition of compiler defined macros

  • Fixed some intra-process related segmentation faults and deadlocks

  • Fixed large data payload protection issues on intra-process

  • Fixed C++17 and VS 2019 warnings

  • Fixed linker problems on some platforms

  • Fixed transient local retransmission after participant drop

  • Fixed assertion failure on persistent writers

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 2.0 (EOL)

Version 2.0.3 (EOL)

It also includes the following improvements:

  1. Increased uniqueness of GUID prefix (#1648)

  2. Upgrade Fast CDR to v1.0.20 (#1793)

This release includes the following bugfixes:

  1. Fixed some race conditions (#1540, #2023)

  2. Fixed SHM issues (#1644, #1895, #2266)

  3. Fixed some interoperability issues (#1624, #1752, #1849)

  4. Fixed Discovery Server 2.0 issues (#1639, #1651, #1761, #1796)

  5. Fixed several issues on QNX systems (#1744, #1773, #1776)

  6. Fix singleton destruction order (#1758)

  7. Fix heartbeat and ACK issues (#1865)

  8. Fix issues in LivelinessManager (#1872, #2147)

  9. Fix multicast issues (#1966, #1905)

  10. Fix TCP reception synchronization (#1981)

  11. XTypes standard compliance and fixes (#2006, #2278)

  12. Other minor fixes (#1558, #1734, #1814, #1935, #1978, #2121)

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 2.0.2 (EOL)

This release includes the following improvements:

  • Improve QNX support

  • Security improvements

  • Fast DDS Quality Declaration (QL 2)

  • Large traffic reduction when using Discovery Server (up to 85-90% for large deployments)

  • Configuration of Clients of Discovery Server using an environment variable

  • A CLI for Fast DDS:

    • This can be used to launch a discovery server

    • Clean SHM directories with one command

  • Shared memory transport enabled by default

  • Solved edge-case interoperability issue with CycloneDDS

  • Add package.xml

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 2.0.1 (EOL)

This release includes the following bug fixes:

  • Fixed sending GAPs to late joiners

  • Fixed asserting liveliness on data reception

  • Avoid calling OpenSSL_add_all_algorithms() when not required

Other improvements:

  • Fixing warnings

PRs in merge order: #1295, #1300, #1304, #1290, #1307.

Note

If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 2.0.0 (EOL)

This release has the following API breaks:

  • eClock API, which was deprecated on v1.9.1, has been removed

  • eprosima::fastrtps::rtps::RTPSDomain::createParticipant methods now have an additional first argument domain_id

  • Data member domainId has been removed from eprosima::fastrtps::rtps::RTPSParticipantAttributes and added to eprosima::fastrtps::ParticipantAttributes

Users should also be aware of the following deprecation announcement:

  • All classes inside the namespace eprosima::fastrtps should be considered deprecated. Equivalent functionality is offered through namespace eprosima::fastdds.

  • Namespaces beneath eprosima::fastrtps are not included in this deprecation, i.e. eprosima::fastrtps::rtps can still be used)

This release adds the following features:

  • Added support for register/unregister/dispose instance

  • Added DDS compliant API. This new API exposes all the functionality of the Publisher-Subscriber Fast RTPS API adhering to the Data Distribution Service (DDS) version 1.4 specification

  • Added Security Logging Plugin (contributed by Cannonical Ltd.)

  • Bump to FastCDR v1.0.14

It also includes the following bug fixes and improvements:

  • Support for OpenSSL 1.1.1d and higher

  • Support for latest versions of gtest

  • Support for FreeBSD

  • Fault tolerance improvements to Shared Memory transport

  • Fixed segfault when no network interfaces are detected

  • Correctly ignoring length of PID_SENTINEL on parameter list

  • Improved traffic on PDP simple mode

  • Reduced CPU and memory usage

Version 1.10 (EOL)

Version 1.10.1 (EOL)

This release includes the following improvements:

  1. Add new CMake option: SHM_TRANSPORT_DEFAULT. Shared Memory (SHM) Transport disabled by default.

  2. Comply with the RTPS standard concerning PID_SENTINEL.

  3. Support for OpenSSL 1.1.1d.

This release includes the following bugfixes:

  1. Fix crash when there are no network interfaces.

  2. Several Shared Memory Transport fixes.

  3. Other minor fixes.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 1.10.0 (EOL)

This release adds the following features:

  • New built-in Shared Memory Transport

  • Transport API refactored to support locator iterators

  • Added subscriber API to retrieve info of first non-taken sample

  • Added parameters to fully avoid dynamic allocations

  • History of built-in endpoints can be configured

  • Bump to FastCDR v1.0.13.

  • Bump to Fast-RTPS-Gen v1.0.4.

  • Require CMake 3.5 but use policies from 3.13

It also includes the following bug fixes and improvements:

  • Fixed alignment on parameter lists

  • Fixed error sending more than 256 fragments.

  • Fix handling of STRICT_REALTIME.

  • Fixed submessage_size calculation on last data_frag.

  • Solved an issue when recreating a publishing participant with the same GUID.

  • Solved an issue where a publisher could block on write for a long time when a new subscriber (late joiner) is matched, if the publisher had already sent a large number of messages.

  • Correctly handling the case where lifespan expires at the same time on several samples.

  • Solved some issues regarding liveliness on writers with no readers.

  • Correctly removing changes from histories on keyed topics.

  • Not reusing cache change when sample does not fit.

  • Fixed custom wait_until methods when time is in the past.

  • Several data races and ABBA locks fixed.

  • Reduced CPU and memory usage.

  • Reduced flakiness of liveliness tests.

  • Allow for more use cases on performance tests.

Several bug fixes on discovery server:

  • Fixed local host communications.

  • Correctly trimming server history.

  • Fixed backup server operation.

  • Fixed timing issues.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen. If you are upgrading from a version older than 1.10.0, regenerating the code is recommended.

Version 1.9 (EOL)

Version 1.9.5 (EOL)

This release includes the following improvements:

  1. Propagate serialization error when reading samples from Subscriber History.

  2. Improvements in test suite.

  3. Improvements to reduce memory consumption.

  4. Update CMake (3.5) using newer policies.

  5. Improve PDP StatefulWriter announcement.

  6. Performance improvements.

  7. Message receiver improvements.

  8. QoS Policies improvements.

This release includes the following bugfixes:

  1. Fix compiler warnings in Windows when building the test suite.

  2. Fix several data races.

  3. Fix History issues.

  4. Fix errors when sending data fragments.

  5. Fix strict real-time behavior.

  6. Fix in Discovery Server.

  7. Fix CMake option.

  8. Fix interoperability issues.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.9.4 (EOL)

This release adds the following features:

  • Intra-process delivery mechanism is now active by default.

  • Synchronous writers are now allowed to send fragments.

  • New memory mode DYNAMIC_RESERVE on history pool.

  • Performance tests can now be run on Windows and Mac.

  • XML profiles for requester and replier.

It also includes the following bug fixes and improvements:

  • Bump to FastCDR v1.0.12.

  • Bump to Fast-RTPS-Gen v1.0.3.

  • Fixed deadlock between PDP and StatefulReader.

  • Improved CPU usage and allocations on timed events management.

  • Performance improvements on reliable writers.

  • Fixing bugs when Intra-process delivery is activated.

  • Reducing dynamic allocations and memory footprint.

  • Improvements and fixes on performance tests.

  • Other minor bug fixes and improvements.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.9.3 (EOL)

This release adds the following features:

  • Participant discovery filtering flags.

  • Intra-process delivery mechanism opt-in.

It also includes the following bug fixes and improvements:

  • Bump to Fast-RTPS-Gen v1.0.2.

  • Bring back compatibility with XTypes 1.1 on PID_TYPE_CONSISTENCY.

  • Ensure correct alignment when reading a parameter list.

  • Add CHECK_DOCUMENTATION cmake option.

  • EntityId_t and GuidPrefix_t have now their own header files.

  • Fix potential race conditions and deadlocks.

  • Improve the case where check_acked_status is called between reader matching process and its acknack reception.

  • RTPSMessageGroup_t instances now use the thread-local storage.

  • FragmentedChangePitStop manager removed.

  • Remove the data fragments vector on CacheChange_t.

  • Only call find_package for TinyXML2 if third-party options are off

  • Allow XMLProfileManager methods to not show error log messages if a profile is not found.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.9.2 (EOL)

This release includes the following feature:

  • Multiple initial PDP announcements.

  • Flag to avoid builtin multicast.

It also adds the following bug fixes and improvements:

  • Bump to Fast-RTPS-Gen v1.0.1.

  • Bump to IDL-Parser v1.0.1.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.9.1 (EOL)

This release includes the following features:

  • Fast-RTPS-Gen is now an independent project.

  • Header eClock.h is now marked as deprecated.

It also adds the following bug fixes and improvements:

  • Bump to FastCDR v1.0.11.

  • Installation from sources documentation fixed.

  • Fixed assertion on WriterProxy.

  • Fixed potential fall through while parsing Parameters.

  • Removed deprecated guards causing compilation errors in some 32 bits platforms.

  • addTOCDRMessage method is now exported in the DLL, fixing issues related with Parameters’ constructors.

  • Improve windows performance by avoiding usage of _Cnd_timedwait method.

  • Fixed reported communication issues by sending multicast through localhost too.

  • Fixed potential race conditions and deadlocks.

  • Eliminating use of acceptMsgDirectTo.

  • Discovery Server framework reconnect/recreate strategy.

  • Removed unused folders.

  • Restored subscriber API.

  • SequenceNumber_t improvements.

  • Added STRICT_REALTIME cmake option.

  • SubscriberHistory improvements.

  • Assertion of participant liveliness by receiving RTPS messages from the remote participant.

  • Fixed error while setting next deadline event in create_new_change_with_params.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.9.0 (EOL)

This release includes the following features:

  • Partial implementation of allocation QoS.

  • Implementation of Discovery Server.

  • Implementation of non-blocking calls.

It also adds the following bug fixes and improvements:

  • Added sliding window to BitmapRange.

  • Modified default behavior for unknown writers.

  • A Flush() method was added to the logger to ensure all info is logged.

  • A test for loading Duration_t from XML was added.

  • Optimized WLP when removing local writers.

  • Some liveliness tests were updated so that they are more stable on Windows.

  • A fix was added to CMakeLists.txt for installing static libraries.

  • A fix was added to performance tests so that they can run on the RT kernel.

  • Fix for race condition on built-in protocols creation.

  • Fix for setting nullptr in a fixed_string.

  • Fix for v1.8.1 not building with -DBUILD_JAVA=ON.

  • Fix for GAP messages not being sent in some cases.

  • Fix for coverity report.

  • Several memory issues fixes.

  • fastrtps.repos file was updated.

  • Documentation for building with Colcon was added.

  • Change CMake configuration directory if INSTALLER_PLATFORM is set.

  • IDL sub-module updated to current version.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.8 (EOL)

Version 1.8.5 (EOL)

This release includes the following bugfixes:

  1. Fix Subscriber History to correctly notify late-joiners in case of KEEP_LAST, RELIABLE, and TRANSIENT_LOCAL.

  2. Fix Writer History behavior when there are no matched readers.

  3. Fix heartbeat and ACK issues.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.8.4 (EOL)

This release adds the following feature:

  • XML profiles for requester and replier

It also has the following important bug fixes:

  • Solved an issue when recreating a publishing participant with the same GUID (either on purpose or by chance)

  • Solved an issue where a publisher could block on write for a long time when, after a large number of samples have been sent, a new subscriber is matched.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen

Version 1.8.3 (EOL)

This release adds the following bug fixes and improvements:

  • Fix serialization of TypeConsistencyEnforcementQosPolicy.

  • Bump to Fast-RTPS-Gen v1.0.2.

  • Bump to IDL-Parser v1.0.1.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen

Version 1.8.2 (EOL)

This release includes the following features:

  • Modified unknown writers default behavior.

  • Multiple initial PDP announcements.

  • Flag to avoid builtin multicast.

  • STRICT_REALTIME compilation flag.

It also adds the following bug fixes and improvements:

  • Fix for setting nullptr in a fixed string.

  • Fix for not sending GAP in several cases.

  • Solve Coverity report issues.

  • Fix issue of fastddsgen failing to open IDL.g4 file.

  • Fix unnamed lock in AESGCMGMAC_KeyFactory.cpp.

  • Improve XMLProfiles example.

  • Multicast is now sent through localhost too.

  • BitmapRange now implements sliding window.

  • Improve SequenceNumber_t struct.

  • Participant’s liveliness is now asserted when receiving any RTPS message.

  • Fix leak on RemoteParticipantLeaseDuration.

  • Modified default values to improve behavior in Wi-Fi scenarios.

  • SubscriberHistory improvements.

  • Removed use of acceptMsgDirectTo.

  • WLP improvements.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen

Version 1.8.1 (EOL)

This release includes the following features:

It also adds the following bug fixes and improvements:

  • Fix for get_change on history, which was causing issues during discovery.

  • Fix for announcement of participant state, which was sending ParticipantBuiltinData twice.

  • Fix for closing multicast UDP channel.

  • Fix for race conditions in SubscriberHistory, UDPTransportInterface and StatefulReader.

  • Fix for lroundl error on Windows in Time_t.

  • CDR & IDL submodules update.

  • Use of java 1.8 or greater for fastddsgen.jar generation.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.8.0 (EOL)

This release included the following features:

It also adds the following improvements and bug fixes:

  • Real-time improvements: non-blocking write calls for best-effort writers, addition of fixed size strings, fixed size bitmaps, resource limited vectors, etc.

  • Duration parameters now use nanoseconds.

  • Configuration of participant mutation tries.

  • Automatic calculation of the port when a value of 0 is received on the endpoint custom locators.

  • Non-local addresses are now filtered from whitelists.

  • Optimization of check for acked status for stateful writers.

  • Linked libs are now not exposed when the target is a shared lib.

  • Limitation on the domain ID has been added.

  • UDP non-blocking send is now optional and configurable via XML.

  • Fix for non-deterministic tests.

  • Fix for ReaderProxy history being reloaded incorrectly in some cases.

  • Fix for RTPS domain hostid being potentially not unique.

  • Fix for participants with different lease expiration times failing to reconnect.

Known issues

  • When using TPC transport, sometimes callbacks are not invoked when removing a participant due to a bug in ASIO.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.7 (EOL)

Version 1.7.3 (EOL)

This release includes the following bugfixes:

  1. Remove inline specifier from public method not defined in header file.

  2. Fix FastRTPS-Gen version generation

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.7.2 (EOL)

This release fixes an important bug:

  • Allocation limits on subscribers with a KEEP_LAST QoS was taken from resource limits configuration and didn’t take history depth into account.

It also has the following improvements:

  • Vendor FindThreads.cmake from CMake 3.14 release candidate to help with sanitizers.

  • Fixed format of gradle file.

Some other minor bugs and performance improvements.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.7.1 (EOL)

This release included the following features:

  • LogFileConsumer added to the logging system.

  • Handle FASTRTPS_DEFAULT_PROFILES_FILE environment variable indicating the default profiles XML file.

  • XML parser made more restrictive and with better error messages.

It also fixes some important bugs: * Fixed discovery issues related to the selected network interfaces on Windows. * Improved discovery times. * Workaround ASIO issue with multicast on QNX systems. * Improved TCP transport performance. * Improved handling of key-only data submessages.

Some other minor bugs and performance improvements.

KNOWN ISSUES

  • Allocation limits on subscribers with a KEEP_LAST QoS is taken from resource limits configuration and doesn’t take history depth into account.

Note: If you are upgrading from a version older than 1.7.0, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.7.0 (EOL)

This release included the following features:

Also bug fixing, allocation and performance improvements.

Note: If you are upgrading from an older version, it is required to regenerate generated source from IDL files using fastddsgen.

Version 1.6 (EOL)

Version 1.6.0 (EOL)

This release included the following features:

Also bug fixing.

Note: If you are upgrading from an older version than 1.4.0, it is advisable to regenerate generated source from IDL files using fastddsgen.

Version 1.5 (EOL)

Version 1.5.0 (EOL)

This release included the following features:

  • Configuration of Fast RTPS entities through XML profiles.

  • Added heartbeat piggyback support.

Also bug fixing.

Note: If you are upgrading from an older version than 1.4.0, it is advisable to regenerate generated source from IDL files using fastddsgen.

Version 1.4 (EOL)

Version 1.4.0 (EOL)

This release included the following:

  • Added secure communications.

  • Removed all Boost dependencies. Fast RTPS is not using Boost libraries anymore.

  • Added compatibility with Android.

  • Bug fixing.

Note: After upgrading to this release, it is advisable to regenerate generated source from IDL files using fastddsgen.

Version 1.3 (EOL)

Version 1.3.1 (EOL)

This release included the following:

  • New examples that illustrate how to tweak Fast RTPS towards different applications.

  • Improved support for embedded Linux.

  • Bug fixing.

Version 1.3.0 (EOL)

This release introduced several new features:

  • Unbound Arrays support: Now you can send variable size data arrays.

  • Extended Fragmentation Configuration: It allows you to setup a Message/Fragment max size different to the standard 64Kb limit.

  • Improved logging system: Get even more introspection about the status of your communications system.

  • Static Discovery: Use XML to map your network and keep discovery traffic to a minimum.

  • Stability and performance improvements: A new iteration of our built-in performance tests will make benchmarking easier for you.

  • ReadTheDocs Support: We improved our documentation format and now our installation and user manuals are available online on ReadTheDocs.

Version 1.2 (EOL)

Version 1.2.0 (EOL)

This release introduced two important new features:

  • Flow Controllers: A mechanism to control how you use the available bandwidth avoiding data bursts. The controllers allow you to specify the maximum amount of data to be sent in a specific period of time. This is very useful when you are sending large messages requiring fragmentation.

  • Discovery Listeners: Now the user can subscribe to the discovery information to know the entities present in the network (Topics, Publishers & Subscribers) dynamically without prior knowledge of the system. This enables the creation of generic tools to inspect your system.

But there is more:

  • Full ROS 2 Support: Fast RTPS is used by ROS 2, the upcoming release of the Robot Operating System (ROS).

  • Better documentation: More content and examples.

  • Improved performance.

  • Bug fixing.